Стрификация условно скомпилированного перечисления в 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
типа, но были бы, вероятно, способы расширить это.