WedX - журнал о программировании и компьютерных науках

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

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

#ifdef DISABLE_UNTIL OTHER_CODE_IS_READY
   foo();
#endif

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

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


  • Каждая версия g++, которую я пробовал, предупреждает об этом, от 2.8.1 до 4.8.1, предупреждает об этом либо предупреждение: мусор в конце аргумента '#ifdef', предупреждение: дополнительные токены в конце директивы #ifdef, либо предупреждение: дополнительные токены в конце директивы #ifdef [включено по умолчанию]. Как не сделали диагностику? 11.10.2013
  • @Кит: g++ myprogram.cpp -o myprogram | grep ! warning 11.10.2013
  • @LightnessRacesinOrbit: это не будет отфильтровывать предупреждения (синтаксис grep неверен, и gcc записывает диагностику в stderr). В любом случае, я думаю, вы размышляете; Я хотел бы знать, как ОП не получил предупреждение. ОП: Вы намеренно отключили предупреждения? 11.10.2013
  • @KeithThompson Я только что написал 5-строчную тестовую программу и скомпилировал ее с помощью: g++ temp.cpp (используя i686-apple-darwin11-llvm-g++-4.2 под MacOS/X 10.8.5) 12.10.2013
  • Какая 5-строчная программа? Вы хотите сказать, что предупреждений не было? 13.10.2013
  • @KeithThompson Да, на моей машине следующее компилируется без предупреждений: #include ‹stdio.h› int main(int, char **) { #ifdef DISABLE_UNTIL OTHER_CODE_IS_READY foo(); #endif вернуть 0; } 13.10.2013
  • (Вам придется повторно вставлять новые строки в нужных местах; я не думаю, что есть способ правильно разместить код в комментарии, извините :() 13.10.2013
  • @JeremyFriesner: Это очень странно. С g++ 4.7.2 я получаю предупреждение: дополнительные токены в конце директивы #ifdef. С clang++ 3.0 я получаю предупреждение: дополнительные токены в конце директивы #ifdef. В любом случае любой соответствующий компилятор должен диагностировать дополнительный токен в файле #ifdef. 13.10.2013

Ответы:


1

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

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

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

Собственная документация 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

Установка GCC Coliru выдает его с -pedantic или без него.

11.10.2013
  • и, конечно же, стандарт не требует прямой диагностики здесь' -- стандарт требует диагностики для любого нарушения синтаксического правила. 13.10.2013
  • @Keith: О да, ты прав ([C++11: 1.4/2]). Я всегда думал о диагностике как об обязательном включении стандартных правил по умолчанию, тогда как на самом деле верно как раз обратное. Спасибо. 13.10.2013

  • 2

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

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

    #if defined(DISABLE_UNTIL) || defined(OTHER_CODE_IS_READY)
        foo();
    #endif
    
    11.10.2013
  • Вы очень хорошо ответили на другой вопрос. 11.10.2013
  • И как это отвечает на вопрос законно ли это? 11.10.2013
  • Я не уверен, чего надеялся добиться автор кода... Я подозреваю, что это была просто опечатка (он случайно набрал пробел, а не подчеркивание). 12.10.2013
  • +1, так как я считаю ответ полезным, даже если он не отвечает на вопрос, законно ли это? часть вопроса. Но что не так с этим кодом, чтобы вы отвергли его как неподходящий/непригодный? 18.06.2019
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]