Сложные однострочные определения условной контрольной суммы

Принимая этот код:

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
Другие вопросы по тегам