Stringifying an conditionally compiled enum in C

7.5k Views Asked by At

Our system has a large number of enums denoting stuff such as events, errors etc.

I'm trying to build infrastructure that would allow us to log each received event or error message as a string (instead of a plain integer), without having to build and maintain two lists for each enum.

I found the X Macro technique quite suitable for my needs. Thus, instead of doing this:

typedef enum
{
   valA,
   valB,
   valC
} some_enum;

const char* some_enum_strings[] =
{                                                                                       
    "valA",
    "valB",
    "valC"
};

I'm doing this:

#define DEF_STRINGIFY(_x_) #_x_,
#define DEF_ENUM(_x_) _x_,

#define ENUM_NAME(_x_) \
    _x_(valA) \
    _x_(valB) \
    _x_(valC) 

typedef enum
{
    SOME_ENUM(DEF_ENUM)
} some_enum;

const char* some_enum_strings[] =
{                                                                                       
    SOME_ENUM(DEF_STRINGIFY)
};

That's all good and well, but the thing is some of our enums are quite big, comprising hundreds of values and filled with conditional compilation, and look a bit more like this

typedef enum
{
   valA,
#if defined (SYS_A)
   valB,
#endif
   valC,
   valD,
#if defined (SYS_B) || defined (SYS_D)
   valE,
#else
   valF,
#endif
   valG
/* etc. */
} some_enum;

As is turns out, C wouldn't allow conditional compilation within a macro. Eclipse claims "Invalid use of macro pasting in macro: SOME_ENUM, and when I try to build the code it fails due to "error: '#' is not followed by a macro parameter" (With the line number matching the first #if statement within the macro).

So now I'm quite stuck, and would appreciate any advice.

Is there a solution to my conundrum?

When suggesting a solution, please note that:

  • I can't have more than one list per enum
  • This solution needs to be applied to a large number of enums (i.e., I can't really put each enum in its own .h file)

Thanks.

1

There are 1 best solutions below

1
On

P99 has P99_DECLARE_ENUM and friends that lets you handle enums quite nicely. You obtain functions that return strings with the names, etc. This should be robust against conditional compilation. The only limit is the total amount of values that you can have in one enum type, but there would be probably ways to extend this.