In practice it is written like like this:
#define MY_ENUM(x) x(MY_A) x(MY_B) x(MY_C)
enum my_enum { MY_ENUM(ENUM_ENTRIES) };
static const char *my_enum_names[] = { MY_ENUM(ENUM_NAMES) };
but one could also make it even more compact if one cared.
That doesn't look any better.
Yes, xmacros have the best compile times, but you can't possibly argue that they are elegant to use compared to the alternatives.