Что именно делает блок #if 0 ..... #endif? - PullRequest
112 голосов
/ 18 мая 2010

In C / C ++

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

#if 0

//Code goes here

#endif

Код просто пропускается и, следовательно, не выполняется?

Ответы [ 9 ]

129 голосов
/ 18 мая 2010

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

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

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

65 голосов
/ 18 мая 2010

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

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

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

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

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

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

Работает, чтобы закомментировать всю вещь. И #if 0 s будут гнездиться друг с другом, вот так:

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

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

17 голосов
/ 18 мая 2010

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

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

Точно так же, как код не существует.

12 голосов
/ 10 июня 2013

Я хотел бы добавить для случая #else:

#if 0
   /* Code here will NOT be complied. */
#else
   /* Code will be compiled. */
#endif


#if 1
   /* Code will be complied. */
#else
   /* Code will NOT be compiled. */
#endif
12 голосов
/ 18 мая 2010

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

В нем говорится, что автор, очевидно, никогда не слышал о системе контроля версий. Который, в свою очередь, говорит вам бежать как можно дальше & hellip;

6 голосов
/ 18 мая 2010

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

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

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

3 голосов
/ 18 мая 2010

Строки, начинающиеся с #, являются директивами препроцессора . Блоки #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 ++, и это плохая привычка ссылаться на такой язык.

1 голос
/ 18 мая 2010

Не совсем

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

Показывает "t.c: 4: 19: предупреждение: отсутствует завершающий символ" с gcc 4.2.4

0 голосов
/ 18 мая 2010

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

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

#ifdef DEBUG
// output to file
#endif

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

...