Что точно делает #if, который делают 0 … #endif блок?

В C/C++

Что, оказывается, кодирует помещенный между #if 0/#endif блок?

#if 0

//Code goes here

#endif

Код просто становится пропущенным и поэтому не становится выполняемым?

115
задан Brian Tompsett - 汤莱恩 24 February 2016 в 17:34
поделиться

8 ответов

Он не только не выполняется, он даже не компилируется.

#if - это команда препроцессора, которая оценивается перед фактическим шагом компиляции. Код внутри этого блока не появляется в скомпилированном двоичном файле.

Он часто используется для временного удаления сегментов кода с намерением включить их позже.

133
ответ дан 24 November 2019 в 02:23
поделиться

Когда препроцессор видит #if, он проверяет, имеет ли следующий токен ненулевое значение. Если это так, он сохраняет код для компилятора. В противном случае он избавляется от этого кода, поэтому компилятор никогда его не видит.

Если кто-то говорит #if 0, он фактически комментирует код, поэтому он никогда не будет скомпилирован. Вы можете думать об этом так же, как если бы они поместили вокруг него / * ... * /. Это не совсем то же самое, но имеет тот же эффект.

Если вы хотите понять, что произошло в деталях, вы можете часто посмотреть. Многие компиляторы позволяют просматривать файлы после запуска препроцессора. Например, в Visual C ++ команда switch / P выполнит препроцессор и поместит результаты в файл .i.

6
ответ дан 24 November 2019 в 02:23
поделиться

Это идентично закомментированию блока, за исключением одного важного отличия: вложение не является проблемой. Рассмотрим этот код:

foo();
bar(x, y); /* x must not be NULL */
baz();

Если я хочу его прокомментировать, я могу попробовать:

/*
foo();
bar(x, y); /* x must not be NULL */
baz();
*/

Bzzt. Ошибка синтаксиса! Почему? Поскольку блочные комментарии не вкладываются, и поэтому (как видно из выделения синтаксиса SO) * / после слова «NULL» завершает комментарий, в результате чего вызов baz не комментируется out, а * / после baz - синтаксическая ошибка. С другой стороны:

#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif

Работает, чтобы закомментировать все это. И #if 0 будут вложены друг в друга, например:

#if 0
pre_foo();
#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif
quux();
#endif

Хотя, конечно, это может немного запутать и превратиться в головную боль обслуживания, если не прокомментировать должным образом.

69
ответ дан 24 November 2019 в 02:23
поделиться

Он постоянно комментирует этот код, так что компилятор никогда его не скомпилирует.

Позже кодер может изменить #ifdef, чтобы этот код компилировался в программе, если захочет.

Это точно так же, как если бы кода не существовало.

17
ответ дан 24 November 2019 в 02:23
поделиться

Что именно делает блок #if 0 ... #endif?

Он говорит вам, что автор, очевидно, никогда не слышал о системе контроля версий. Что, в свою очередь, говорит вам, что нужно бежать как можно дальше...

13
ответ дан 24 November 2019 в 02:23
поделиться

Строки, начинающиеся с #, являются директивами препроцессора. #if 0 [...] #endif блоки не попадают в компилятор и не генерируют машинный код.

Вы можете продемонстрировать, что происходит с препроцессором с помощью исходного файла ifdef.cxx:

#if 0
This code will not be compiled
#else
int i = 0;
#endif

Запустив gcc -E ifdef.cxx, вы увидите, что будет скомпилировано.

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

Также ответ может быть одинаковым для C и C++, но не существует языка под названием C/C++, и ссылаться на такой язык - плохая привычка.

3
ответ дан 24 November 2019 в 02:23
поделиться

Не совсем

int main(void)
{
   #if 0
     the apostrophe ' causes a warning
   #endif
   return 0;
}

Он показывает "t.c:4:19: warning: missing terminating ' character" с gcc 4.2.4

1
ответ дан 24 November 2019 в 02:23
поделиться

Это дешевый способ закомментировать, но я подозреваю, что он может иметь отладочный потенциал. Например, предположим, у вас есть сборка, которая выводит значения в файл. Возможно, вы не хотите, чтобы это было в окончательной версии, поэтому вы можете использовать #if 0... #endif.

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

#ifdef DEBUG
// output to file
#endif

Вы можете сделать что-то подобное, и это может иметь больше смысла, и все, что вам нужно сделать, это определить DEBUG, чтобы увидеть результаты.

0
ответ дан 24 November 2019 в 02:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: