Стрификация условно скомпилированного перечисления в C

Наша система имеет большое количество перечислений, обозначающих такие вещи, как события, ошибки и т. Д.

Я пытаюсь создать инфраструктуру, которая позволила бы нам регистрировать каждое полученное событие или сообщение об ошибке в виде строки (вместо простого целого числа) без необходимости создавать и поддерживать два списка для каждого перечисления.

Я нашел технику X Macro вполне подходящей для моих нужд. Таким образом, вместо этого:

typedef enum
{
   valA,
   valB,
   valC
} some_enum;

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

Я делаю это:

#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)
};

Это все хорошо и хорошо, но дело в том, что некоторые из наших перечислений довольно большие, содержат сотни значений и заполнены условной компиляцией, и выглядят немного так

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;

Как выясняется, C не разрешает условную компиляцию в макросе. Eclipse заявляет: "Неправильное использование макроса, вставляемого в макрос: SOME_ENUM, и когда я пытаюсь построить код, происходит сбой из-за"error: '#' не сопровождается параметром макроса " (с номером строки, соответствующим первому оператору #if в макросе).

Так что теперь я застрял и был бы признателен за любые советы.

Есть ли решение моей головоломки?

Предлагая решение, обратите внимание, что:

  • Я не могу иметь более одного списка на каждое перечисление
  • Это решение должно быть применено к большому количеству перечислений (т.е. я не могу поместить каждое перечисление в отдельный файл.h)

Благодарю.

1 ответ

P99 имеет P99_DECLARE_ENUM и друзья, которые позволяют вам справиться enumдовольно мило. Вы получаете функции, которые возвращают строки с именами и т. Д. Это должно быть устойчиво к условной компиляции. Единственным ограничением является общее количество значений, которые вы можете иметь в одном enum типа, но были бы, вероятно, способы расширить это.

Другие вопросы по тегам