A bit cleaner setup, in my opinion, makes the &quot;x macro&quot; an argument to the user-defined macro, rather than depending on #include.  For example, to define an enum along with a string representation function for it:<p><pre><code>    #define DEFINE_ENUM(name, variants) \
      enum name { \
        variants(DEFINE_ENUM_VARIANT_ITSELF) \
      }; \
      const char *repr_##name(enum name e) { \
        switch (e) { \
          variants(DEFINE_ENUM_VARIANT_REPR_CASE) \
          default: return &quot;?&quot;; \
        } \
      }
    #define DEFINE_ENUM_VARIANT_ITSELF(variant) variant,
    #define DEFINE_ENUM_VARIANT_REPR_CASE(variant) \
      case variant: return #variant;

    &#x2F;&#x2F; client code:

    #define foo_variants(x) \
      x(FOO_1) \
      x(FOO_2)
    DEFINE_ENUM(foo, foo_variants)</code></pre>