Зачем использовать #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 в производственном коде.