Сложные однострочные определения условной контрольной суммы
Принимая этот код:
typedef enum CHECKSUM { DENY = 0, ALLOW = 1 } checksum;
#define terminal(x, str) static checksum* terminal_##x; { if(!strcmp(#str, "static")) { static checksum local = ALLOW; terminal_##x = &local; } else { checksum local = DENY; terminal_##x = &local; } }
То, что я хочу, чтобы этот код сделал, это определить макрос-функцию с двумя параметрами x
для имени и str
для определенного типа. Функция макроса объявляет static checksum*
с именем terminal_
соединенный с именем x
, Затем он открывает новую область видимости и определяет конкретный тип str
и использовать strcmp
проверить, равно ли оно static
, Если так.. тогда он объявляет тип переменной static checksum
, инициализируется с ALLOW
и делает объявленный указатель, указывающий на него, если он не равен, тогда он объявляет тип переменной checksum
, инициализируется с DENY
и установите указатель, чтобы указать на него. Тогда мы можем вызвать макрос так:
int main(void)
{
int i = 0;
while(*terminal_name == ALLOW) { terminal(name, static) if(i > 200) { *terminal_name = DENY; } i++; }
return 0;
// Note that this is only an example usage. The real usage of this is far more long and complicated.
}
Код хорошо скомпилирован на C89 и не вызывает ошибок и предупреждений. На первый взгляд.. это работает. Но, как вы можете видеть сами по себе... это выглядит очень подозрительно.
Это правильный способ, которым я делаю это?
Пожалуйста, спросите, есть ли у вас проблемы с пониманием чего-либо.
1 ответ
Трудно сказать, является ли макрос разумным или плохим, не зная больше о вашей программе.
Стилистически вы можете использовать обратную косую черту, чтобы разбить макрос на несколько строк. Это сделает его намного более читабельным и менее "подозрительным".
#define terminal(x, str) \
static checksum* terminal_##x; \
{ \
if (!strcmp(#str, "static")) { \
static checksum local = ALLOW; \
terminal_##x = &local; \
} \
else { \
checksum local = DENY; \
terminal_##x = &local; \
} \
}
С помощью strcmp
решить, использовать ли static
или нет действительно тереть меня в ту сторону. Это проверка во время выполнения, влияющая на решение во время компиляции. Я бы предложил сделать два отдельных макроса, скажем LOCAL_TERMINAL
а также STATIC_TERMINAL
вместо того, чтобы отключать аргумент макроса.
#define LOCAL_TERMINAL (x) checksum terminal_##x = DENY
#define STATIC_TERMINAL(x) static checksum terminal_##x = ALLOW