Зачем использовать #if 0 для комментирования блока?

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

Это только я или это ужасный стиль кодирования

if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name);
else sprintf(username,"%d",user_id);

И почему код переноса не предназначен для компиляции в

#if 0
....
#endif

Вместо комментариев?


РЕДАКТИРОВАТЬ: Так, как некоторые объяснили ниже, это связано с возможностью flummox /* */, который я не осознавал.

Но я до сих пор не понимаю, почему бы просто не использовать инструменты вашей среды программирования или макросы любимого текстового редактора, чтобы блокировать комментирование с помощью "//"

разве это не было бы НАМНОГО более простым и легким для понимания визуально пропустить?


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

13 ответов

Решение

#if 0 используется довольно часто, когда удаленный блок содержит блок-комментарии

Я не скажу, что это хорошая практика, но я вижу это довольно часто.

Однострочный оператор flow-control+ достаточно прост для понимания, хотя я лично его избегаю (и большинство руководств по кодированию, над которыми я работал, запрещают)

Кстати, я бы, вероятно, отредактировал заголовок, чтобы он был несколько полезен: "Зачем использовать #if 0 вместо блочных комментариев"

Если у вас есть следующее

#if 0
        silly();
        if(foo)
           bar();
        /* baz is a flumuxiation */
        baz = fib+3;
#endif

Если вы наивно замените #if 0/#endif с /* */, это приведет к тому, что комментарий закончится сразу после flumuxiation, вызывая синтаксическую ошибку, когда вы нажмете */ на месте #endif выше..

РЕДАКТИРОВАТЬ: одна последняя заметка, часто #if 0 Синтаксис просто используется при разработке, особенно если вам нужно поддерживать несколько версий или зависимостей или аппаратных платформ. Это не является необычным для кода, который будет изменен на

#ifdef _COMPILED_WITHOUT_FEATURE_BAZ_
    much_code();
#endif

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

В то время как вы разработчик, просто начинаете работать, хотя... #if 0 довольно часто, если вы не уверены, что старый код все еще имеет значение.

Комментарии есть комментарии. Они описывают код.

Код, который исключается из компиляции, является кодом, а не комментариями. Это будет часто включать комментарии, которые описывают код, который не компилируется, на данный момент /

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

Помимо проблемы с вложенностью комментариев в стиле C, блокировка кода с помощью #if 0 Преимущество заключается в возможности свертываться, если вы используете редактор, который поддерживает свертывание кода. Это также очень легко сделать в любом редакторе, тогда как отключение больших блоков кода с комментариями в стиле C++ может быть громоздким без поддержки редактора / макросов.

Также многие #if 0 блоки имеют else блок тоже. Это дает простой способ переключения между двумя реализациями / алгоритмами и, вероятно, менее подвержен ошибкам, чем массовое комментирование одного раздела и массовое раскомментирование другого. Тем не менее, вам будет лучше использовать что-то более читабельное, как #if DEBUG в этом случае.

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

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

Имена переменных могли бы быть лучше, и, вероятно, было бы безопаснее использовать snprintf или возможно strncpy,

Если вы думаете, что это может быть лучше, как бы вы хотели, чтобы это выглядело?

Я мог бы сделать небольшое изменение:

char username[32];
strncpy(username, 30, (pwbuf ? pwbuf->pw_name : user_id));
username[31] = '\0';

Очевидно, что у каждого свое мнение по этому поводу. Так вот мой:

Я бы никогда не написал код, подобный описанному выше, и меньше думал бы о всех, кто это делал. Я не могу сосчитать, сколько раз люди думают, что это нормально - уйти без брекетов, а потом их укусила.

Поместить оператор управления в одну строку с блоком кода еще хуже; отсутствие отступа затрудняет просмотр контроля потока во время чтения. После нескольких лет написания кода вы привыкли к возможности быстро и точно читать и интерпретировать код, при условии, что вы можете полагаться на определенные визуальные подсказки. Обойти эти реплики для "особых случаев" означает, что читатель должен остановиться и сделать двойной дубль, без веской причины.

#if (0)с другой стороны, это нормально во время разработки, но должно быть удалено, когда код "стабилен" (или хотя бы заменить 0 с некоторым значимым именем символа препроцессора).

#if - это макрос, который проверяет условие, записанное рядом с ним, поскольку '0' представляет ложь, это означает, что блок кода, записанный между '#if 0' и '#endif', не будет скомпилирован и, следовательно, может рассматриваться как комментарии.

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

Пример:

#if 0
int a;
int b;
int c = a + b;
#endif

Раздел, написанный между "#if 0" и "#endif", считается комментарием.

Возникают вопросы: "/* … */" можно использовать для написания комментариев в программе, тогда почему "#if 0"?

Ответ: Это потому, что, #if 0 может использоваться для вложенных комментариев, но вложенные комментарии не поддерживаются "/* … */"

Что такое вложенные комментарии? Вложенные комментарии означают комментарии под комментариями и могут использоваться в различных случаях, например:

Давайте возьмем пример того, что вы написали код, как показано ниже:

Теперь кто-то просматривает ваш код и хочет прокомментировать весь этот фрагмент кода в вашей программе, потому что он не чувствует потребности в этом фрагменте кода. Обычный подход к этому будет:

Выше приведен пример вложенных комментариев. Проблема с приведенным выше кодом заключается в том, что как только встречается первый " /" после "/ ", комментарий на этом заканчивается. т.е. в приведенном выше примере утверждение: int d = ab; не комментируется.

Это решается с помощью "если 0":

Здесь мы использовали вложенные комментарии, используя #if 0.

Пункты выше отмеченные. Но мониторы широкоформатные, и все, в эти дни я вроде не против

if (pwbuf) sprintf(username,"%s",pwbuf->pw_name);
else       sprintf(username,"%d",user_id);

Кажется, на моем экране слишком много горизонтального пространства и недостаточно вертикального!

Кроме того, если блок кода уже имеет директивы препроцессора, не используйте #if 0; если код уже имеет блочные комментарии, не используйте /* */, Если у него уже есть оба, либо прибегните к редактору, у которого есть Ctrl+/, чтобы закомментировать множество строк. Если нет, вы набиты, удалите код прямо!

Вау там! Не переусердствуйте...

Я бы назвал это небрежным для большего расстояния, чем что-либо еще. У меня было время, когда я находил, что лучше размещать короткие заявления в одной строке с их IF, хотя эти заявления растягивают его.

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

if (pwbuf) 
  sprintf(username,"%s",pwbuf->pw_name); 
else 
  sprintf(username,"%d",user_id); 

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

if (pwbuf) 
{
  sprintf(username,"%s",pwbuf->pw_name); 
}
else
{ 
  sprintf(username,"%d",user_id); 
}

Могу назвать несколько причин использования:

  • комментарии не вкладываются, а прямые;

  • Это более удобно: если вы хотите временно включить отключенный блок кода, с помощью #if 0 тебе просто нужно положить 1вместо . С участием /* */ вы должны удалить оба /* а также */;

  • вы можете поместить значимый макрос вместо 0, нравиться ENABLE_FEATURE_FOO;

  • инструменты автоматического форматирования будут форматировать код внутри блока, но игнорировать закомментированный код;

  • легче найти #if чем искать комментарии;

  • он лучше работает с VCS, потому что вы не трогаете исходный код, а просто добавляете строки вокруг него.

if ( pwbuf ) sprintf(username,"%s",pwbuf->pw_name);
else sprintf(username,"%d",user_id);

Идиоматичный и лаконичный. Если бы к нему прикоснулись более 2 или 3 раз, я бы поставил его в скобки и на следующей строчке. Это не очень удобно, если вы добавляете информацию о регистрации или другие условия.

#if 0
....
#endif

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

/* line comment */
...
/* line comment again */

Так как блок комментариев C не вкладывается.

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

if (strcmp(s, "foo") == 0)
{
    bitmap = 0x00000001UL;
    bit = 0;
}
else if (strcmp(s, "bar") == 0)
{
    bitmap = 0x00000002UL;
    bit = 1;
}
else if (strcmp(s, "baz") == 0)
{
    bitmap = 0x00000003UL;
    bit = 2;
}
else if (strcmp(s, "qux") == 0)
{
    bitmap = 0x00000008UL;
    bit = 3;
}
else
{
    bitmap = 0;
    bit = -1;
}

и краткая версия:

if      (strcmp(s, "foo") == 0) { bitmap = 0x00000001UL; bit = 0;  }
else if (strcmp(s, "bar") == 0) { bitmap = 0x00000002UL; bit = 1;  }
else if (strcmp(s, "baz") == 0) { bitmap = 0x00000003UL; bit = 2;  }
else if (strcmp(s, "qux") == 0) { bitmap = 0x00000008UL; bit = 3;  }
else                            { bitmap = 0;            bit = -1; }

Ошибки гораздо чаще прыгают прямо в лицо.

Отказ от ответственности: Этот пример является надуманным, как я уже сказал. Не стесняйтесь обсуждать использование strcmp, магических чисел и будет ли лучше подход на основе таблиц.;)

#if 0 ... #endif довольно часто встречается в старом C-коде. Причина в том, что комментирование с комментариями в стиле C /* .... */ не работает, потому что комментарии не вкладываются.

Хотя это и распространено, я бы сказал, что в современном коде нет места. Люди делали это в старину, потому что их текстовые редакторы не могли автоматически блокировать большие разделы комментариев. Более того, они не имели надлежащего контроля исходного кода, как сейчас. Нет оправдания тому, чтобы оставить комментарий или #ifdef'd в производственном коде.

Другие вопросы по тегам