Строгание условно скомпилированного перечисления в 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, и когда я пытаюсь создать код, который он сбой из-за" ошибки: "#" не сопровождается параметром макроса "(с номером строки, соответствующим первому оператору #if внутри макроса).
Итак, теперь я совсем застрял и буду благодарен за любые советы.
Есть ли решение моей головоломки?
Если вы предлагаете решение, обратите внимание, что:
- У меня не может быть более одного списка на enum
- Это решение должно применяться к большому количеству перечислений (т.е. я не могу поместить каждое перечисление в свой собственный файл .h)
Спасибо.
Ответы
Ответ 1
P99 имеет P99_DECLARE_ENUM
и друзей, которые позволяют вам отлично справляться с enum
. Вы получаете функции, возвращающие строки с именами и т.д. Это должно быть устойчивым к условной компиляции. Единственным ограничением является общее количество значений, которое вы можете иметь в одном типе enum
, но, вероятно, были бы способы его расширения.