#ifdef с несколькими токенами, это законно?

Сегодня я наткнулся на некоторый код C ++, который содержит предложение #ifdef, например:

#ifdef DISABLE_UNTIL OTHER_CODE_IS_READY
foo();
#endif

Обратите внимание на пробел между «DISABLE_UNTIL» и «OTHER_CODE_IS_READY». По сути, в строке #ifdef указаны два токена.

У меня вопрос, это законный код C ++? (g ++ компилирует его без ошибок и, по-видимому, просто игнорирует второй токен). И если это законно, должен ли второй токен иметь какой-либо эффект?

6

Решение

[C++11 16.1], [C++11 16.5] и, кстати, [C99 6.10.1/4] все говорят, что это недействительно.

если-группа:
# if константа-выражение новая линия группавыбирать
# ifdef идентификатор новая линия группавыбирать
# ifndef идентификатор новая линия группавыбирать

Только один идентификатор является законным.

Собственная документация GCC соглашается с тем,.

Мои собственные тесты предположить, что принимается только первый идентификатор, а второй просто отбрасывается; это может облегчить реализацию, но стандарт требует диагностики здесь, так что вы должны увидеть это при использовании -pedantic пометить хотя бы.

#include <iostream>
using namespace std;

#define A
#define B

int main() {
#ifdef A
std::cout << "a ";
#endif

#ifdef B
std::cout << "b ";
#endif

#ifdef C
std::cout << "c ";
#endif

#ifdef B C
std::cout << "bc ";
#endif

#ifdef C B
std::cout << "cb ";
#endif

return 0;
}

// Output: "a b bc"// Note: "cb" *not* output

Установка Coliru GCC испускает это с или без -pedantic.

6

Другие решения

Синтаксис, который вы разместили, не является законным, и предполагаемое значение неясно.

В зависимости от того, что вы надеетесь достичь, можете ли вы использовать || или же && объединить их?
(конечно, если это чужой код, я бы просто отклонил его как неуместный / непригодный для использования)

#if defined(DISABLE_UNTIL) || defined(OTHER_CODE_IS_READY)
foo();
#endif
11

По вопросам рекламы [email protected]