it-roy-ru.com

_DEBUG против NDEBUG

Какое определение препроцессора следует использовать для указания отладочных разделов кода?

Используйте #ifdef _DEBUG или #ifndef NDEBUG, или есть лучший способ сделать это, например, #define MY_DEBUG?

Я думаю, что _DEBUG специфичен для Visual Studio, это стандарт NDEBUG?

122
deft_code

Visual Studio определяет _DEBUG, когда вы указываете параметр /MTd или /MDd, NDEBUG отключает утверждения стандарта C. Используйте их при необходимости, например, _DEBUG, если вы хотите, чтобы ваш код отладки соответствовал Методы отладки MS CRT и NDEBUG, если вы хотите быть совместимым с assert().

Если вы определяете свои собственные отладочные макросы (и вы не взламываете компилятор или среду выполнения C), избегайте начинать имена с подчеркивания, так как они зарезервированы.

106
Christoph

Я полагаюсь на NDEBUG, потому что он единственный, чье поведение стандартизировано для компиляторов и реализаций (см. Документацию для стандартного макроса assert). Негативная логика - это небольшая скорость чтения, но это обычная идиома, к которой можно быстро адаптироваться.

Полагаться на что-то вроде _DEBUG - значит полагаться на детали реализации конкретного компилятора и реализации библиотеки. Другие компиляторы могут или не могут выбрать то же соглашение.

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

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

39
Adrian McCarthy

Является ли стандарт NDEBUG?

Да, это стандартный макрос с семантикой "Не отлаживать" для стандартов C89, C99, C++ 98, C++ 2003, C++ 2011, C++ 2014. В стандартах нет макросов _DEBUG.

Стандарт C++ 2003 отправляет читателя на "стр. 326" в "17.4.2.1 Заголовки" к стандарту C.

Этот NDEBUG похож на Это так же, как стандартная библиотека C.

В C89 (программисты на C назвали этот стандарт стандартом C) в разделе "4.2 ДИАГНОСТИКА" было сказано

http://port70.net/~nsz/c/c89/c89-draft.html

Если NDEBUG определен как имя макроса в той точке исходного файла, в которую он включен, макрос assert определяется просто как

     #define assert(ignore) ((void)0)

Если взглянуть на значение макросов _DEBUG в Visual Studio https://msdn.Microsoft.com/en-us/library/b0084kay.aspx , то будет видно, что этот макрос автоматически определяется Ваш выбор языковой версии библиотеки времени выполнения.

36
bruziuz

Макрос NDEBUG контролирует, являются ли операторы assert () активными или нет.

На мой взгляд, это отдельно от любой другой отладки - поэтому я использую что-то кроме NDEBUG для управления отладочной информацией в программе. То, что я использую, варьируется в зависимости от структуры, с которой я работаю; разные системы имеют разные разрешающие макросы, и я использую все, что подходит.

Если рамки отсутствуют, я бы использовал имя без начального подчеркивания; они, как правило, зарезервированы для "реализации", и я стараюсь избегать проблем с коллизиями имен - вдвойне, когда имя является макросом.

13
Jonathan Leffler

Будьте последовательны, и не важно, какой. Также, если по какой-то причине вам необходимо взаимодействовать с другой программой или инструментом, используя определенный идентификатор DEBUG, это легко сделать.

#ifdef THEIRDEBUG
#define MYDEBUG
#endif //and vice-versa
6
Earlz

К сожалению, "DEBUG" сильно перегружен. Например, рекомендуется всегда генерировать и сохранять файл pdb для сборок RELEASE. Что означает один из флагов -Zx и параметр компоновщика -DEBUG. Хотя _DEBUG относится к специальным отладочным версиям библиотеки времени выполнения, таким как вызовы malloc и free. Тогда NDEBUG отключит утверждения.

3
James