You don't need to rely on the preprocessor to ensure your enums and strings are in sync. To me using macros tend to make the code harder to read.
enum fruit
{
APPLE = 0,
ORANGE,
GRAPE,
BANANA,
/* etc. */
FRUIT_MAX
};
const char * const fruit_str[] =
{
[BANANA] = "banana",
[ORANGE] = "orange",
[GRAPE] = "grape",
[APPLE] = "apple",
/* etc. */
};
Note: the strings in the fruit_str
array don't have to be declared in the same order as the enum items.
printf("enum apple as a string: %s\n", fruit_str[APPLE]);
If you are afraid to forget one string, you can add the following check:
#define ASSERT_ENUM_TO_STR(sarray, max) \
typedef char assert_sizeof_##max[(sizeof(sarray)/sizeof(sarray[0]) == (max)) ? 1 : -1]
ASSERT_ENUM_TO_STR(fruit_str, FRUIT_MAX);
An error would be reported at compile time if the amount of enum items does not match the amount of strings in the array.