В других ответах этот вопрос уже описан более четко, но для полноты изложения здесь используется подход x-macro, если вы хотите пойти по этому пути и рискнуть яростью своего коллеги.
X-Макросы - это форма генерации кода, использующая встроенный препроцессор Си.Цель состоит в том, чтобы свести к минимуму повторение, хотя и с некоторыми недостатками:
- Исходный файл, который генерирует перечисления и структуры с использованием препроцессора, может показаться сложным, если вы к ним не привыкли.
- По сравнению с внешним сценарием сборки, который генерирует исходные файлы, с x-макросами вы никогда не увидите, как сгенерированный код выглядит во время компиляции, если вы не используете настройку компилятора и не проверяете предварительно обработанный файл вручную.
- Поскольку вы не видите предварительно обработанные выходные данные, вы не можете использовать отладчик для пошагового выполнения сгенерированного кода так же, как и с кодом, сгенерированным внешним сценарием.
Вы начинаете ссоздание списка макросов вызовов в отдельном файле, например elements.inc
, без определения того, что макрос действительно делает в этой точке:
// elements.inc
// each row passes a set of parameters to the macro,
// although at this point we haven't defined what the
// macro will output
XMACRO(TOTO, 18, French)
XMACRO(TITI, 27, English)
XMACRO(TATA, 45, Spanish)
И затем вы каждый раз определяете макросВы должны включить этот список, чтобы каждый вызов отображался в одной строке конструктора.t вы хотите создать - и вы обычно повторяете это несколько раз подряд, то есть
// concatenate id with "_IND" to create enums, ignore code and description
// (notice how you don't need to use all parameters each time)
// e.g. XMACRO(TOTO, 18, French) => TOTO_IND,
#define XMACRO(id, code, description) id ## _IND,
typedef enum
{
# include "elements.inc"
ELEMENTS_COUNT
}
Elements;
#undef XMACRO
// create struct entries
// e.g. XMACRO(TOTO, 18, French) => [TOTO_IND] = { "TOTO", 18, "French" },
#define XMACRO(id, code, description) [id ## _IND] = { #id, code, #description },
const MyElements elems[] = {
{
# include "elements.inc"
};
#undef XMACRO
, который будет предварительно обработан в нечто вроде:
typedef enum
{
TOTO_IND,
TITI_IND,
TATA_IND,
ELEMENTS_COUNT
}
Elements;
const MyElements elems[] = {
{
[TOTO_IND] = { "TOTO", 18, "French" },
[TITI_IND] = { "TITI", 27, "English" },
[TATA_IND] = { "TATA", 45, "Spanish" },
};
Очевидно, частое обслуживаниесписок становится проще, за счет того, что генерирующий код становится более запутанным.