Hacker News new | past | comments | ask | show | jobs | submit login

The X-macro pattern comes to mind:

  #define LIST_ERROR_TYPES(X) \
    X(OK, "") \
    X(ERR_OOM, "out of memory") \
    X(ERR_BAD_STRING_ENCODING, "string was invalid utf-8") \
    ...

  #define DEF_ENUM(ident,_) ident,
  typedef enum { LIST_ERROR_TYPES(DEF_ENUM) } err_t;

  const char *get_err_msg(err_t err) {
  #define IDENT2MSG(ident,msg) case ident: return msg;
    switch (err) {
    LIST_ERROR_TYPES(IDENT2MSG)
    default: return "unknown error";
    }
  }
Which turns out to be useful for more than just error messages (which is still useful in C++ if you're avoiding exceptions). Recently, for example, I did something like that to map a small fixed set of object properties to database columns.

If you want to see some actual code, I use X-macros, as well as other macros, heavily in the test suite for my (very) WIP programming language: https://github.com/alpha123/yu/tree/master/test

There's some other interesting and generic macros that I frequently use in there too: https://github.com/alpha123/yu/blob/master/src/yu_common.h




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: