#ifdef vs #if - что лучше / безопаснее в качестве метода включения / выключения компиляции отдельных разделов кода? - PullRequest
108 голосов
/ 25 сентября 2008

Это может быть вопросом стиля, но в нашей команде разработчиков есть некоторая разница, и мне было интересно, есть ли у кого-нибудь еще какие-либо идеи по этому вопросу ...

По сути, у нас есть некоторые отладочные операторы печати, которые мы отключаем во время обычной разработки. Лично я предпочитаю делать следующее:

//---- SomeSourceFile.cpp ----

#define DEBUG_ENABLED (0)

...

SomeFunction()
{
    int someVariable = 5;

#if(DEBUG_ENABLED)
    printf("Debugging: someVariable == %d", someVariable);
#endif
}

Некоторые команды предпочитают следующее:

// #define DEBUG_ENABLED

...

SomeFunction()
{
    int someVariable = 5;

#ifdef DEBUG_ENABLED
    printf("Debugging: someVariable == %d", someVariable);
#endif
}

... какой из этих методов звучит для вас лучше и почему? Мне кажется, что первое безопаснее, потому что всегда есть что-то определенное и нет опасности, что оно может разрушить другие определения в другом месте.

Ответы [ 18 ]

2 голосов
/ 11 июня 2013

Это вообще не вопрос стиля. Также вопрос, к сожалению, неверный. Вы не можете сравнивать эти директивы препроцессора в смысле лучшего или более безопасного.

#ifdef macro

означает «если макрос определен» или «если макрос существует». Значение макроса здесь не имеет значения. Это может быть что угодно.

#if macro

если всегда сравнивать со значением. В приведенном выше примере это стандартное неявное сравнение:

#if macro !=0

пример использования # if

#if CFLAG_EDITION == 0
    return EDITION_FREE;
#elif CFLAG_EDITION == 1
    return EDITION_BASIC;
#else
    return EDITION_PRO;
#endif

теперь вы можете добавить определение CFLAG_EDITION либо в свой код

#define CFLAG_EDITION 1 

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

2 голосов
/ 25 сентября 2008

Первое мне кажется понятнее. Кажется более естественным сделать его флагом по сравнению с определенным / не определенным.

2 голосов
/ 25 сентября 2008

Оба точно эквивалентны. В идиоматическом использовании #ifdef используется просто для проверки определенности (и того, что я бы использовал в вашем примере), тогда как #if используется в более сложных выражениях, таких как #iffined (A) && !fined (B).

2 голосов
/ 25 сентября 2008

Немного OT, но включение / выключение ведения журнала с помощью препроцессора определенно неоптимально в C ++. Существуют хорошие инструменты ведения журналов, такие как Apache log4cxx , которые имеют открытый исходный код и не ограничивают распространение вашего приложения. Они также позволяют вам изменять уровни журналирования без перекомпиляции, имеют очень низкие накладные расходы, если вы выключаете регистрацию, и дают вам возможность полностью отключить регистрацию в рабочей среде.

1 голос
/ 04 августа 2017

Я использовал #ifdef, но когда я переключился на Doxygen для документации, я обнаружил, что закомментированные макросы не могут быть задокументированы (или, по крайней мере, Doxygen выдает предупреждение). Это означает, что я не могу задокументировать макросы переключателя функций, которые в данный момент не включены.

Хотя макросы можно определить только для Doxygen, это означает, что макросы в неактивных частях кода также будут документированы. Я лично хочу показать переключатели функций, а в остальном только документировать то, что в данный момент выбрано. Кроме того, это делает код довольно грязным, если существует много макросов, которые должны быть определены только тогда, когда Doxygen обрабатывает файл.

Поэтому в этом случае лучше всегда определять макросы и использовать #if.

0 голосов
/ 17 января 2018

Существует различие в случае другого способа указания условного определения для драйвера:

diff <( echo | g++ -DA= -dM -E - ) <( echo | g++ -DA -dM -E - )

выход:

344c344
< #define A 
---
> #define A 1

Это означает, что -DA является синонимом для -DA=1, и если значение не указано, то это может привести к проблемам в случае использования #if A.

0 голосов
/ 25 сентября 2008

Кроме того, вы можете объявить глобальную константу и использовать C ++ if вместо препроцессора #if. Компилятор должен оптимизировать неиспользуемые ветки для вас, и ваш код будет чище.

Вот что C ++ Gotchas Стивена С. Дьюхерста говорит об использовании # if.

0 голосов
/ 25 сентября 2008

Я всегда использовал флаги #ifdef и компилятора, чтобы определить его ...

...