Какое определение препроцессора следует использовать для указания отладочных разделов кода?
Используйте #ifdef _DEBUG
или #ifndef NDEBUG
или есть лучший способ сделать это, например #define MY_DEBUG
?
Я думаю, что _DEBUG
Visual Studio специфичен, стандарт NDEBUG?
Да, это стандартный макрос с семантикой «Не отлаживать» для стандартов C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014. В стандартах нет
_DEBUG
макросов.Стандарт C ++ 2003 отправляет читателю на «странице 326» в «17.4.2.1 заголовки» к стандарту C.
В C89 (программисты на C назвали этот стандарт стандартом C) в разделе «4.2 ДИАГНОСТИКА» было сказано
Если вы посмотрите на значение
_DEBUG
макросов в Visual Studio https://msdn.microsoft.com/en-us/library/b0084kay.aspx, то увидите, что этот макрос автоматически определяется вашим выбором языковой версии библиотеки времени выполнения.источник
Я полагаюсь
NDEBUG
, потому что это единственный, чье поведение стандартизировано по компиляторам и реализациям (см. Документацию для стандартного макроса assert). Негативная логика - это небольшая скорость чтения, но это обычная идиома, к которой можно быстро адаптироваться.Полагаться на что-то вроде
_DEBUG
- значит полагаться на детали реализации конкретного компилятора и реализации библиотеки. Другие компиляторы могут или не могут выбрать то же соглашение.Третий вариант - определить собственный макрос для вашего проекта, что вполне разумно. Наличие собственного макроса обеспечивает переносимость между реализациями и позволяет включать или отключать код отладки независимо от утверждений. Хотя, в общем, я не советую иметь разные классы отладочной информации, которые включаются во время компиляции, так как это приводит к увеличению количества конфигураций, которые вы должны построить (и протестировать) для, возможно, небольшой выгоды.
При использовании любого из этих вариантов, если вы используете сторонний код в качестве части своего проекта, вы должны знать, какое соглашение оно использует.
источник
#if !defined(NDEBUG)
<- @HostileFork - это не то, что вы имели в виду?#if
нет#ifdef
?#ifdef NDEBUG
... но затем обратим особое внимание на отрицательную логику с помощью#if !defined(NDEBUG)
. В противном случае это немного трудно поймать в#ifndef NDEBUG
"Макрос
NDEBUG
контролирует,assert()
являются ли операторы активными или нет.На мой взгляд, это отдельно от любой другой отладки - поэтому я использую что-то кроме
NDEBUG
контроля информации отладки в программе. То, что я использую, варьируется в зависимости от структуры, с которой я работаю; разные системы имеют разные разрешающие макросы, и я использую то, что подходит.Если рамки отсутствуют, я бы использовал имя без начального подчеркивания; они, как правило, зарезервированы для «реализации», и я стараюсь избегать проблем с конфликтами имен - вдвойне, когда имя является макросом.
источник
#if
управляемый код в другую.assert(huge_object.IsValid());
может быть медленным, аassert(ptr != nullptr);
может и нет. Я согласен с Джонатаном в том, что ведение журнала и трассировка должны, вероятно, отличаться от утверждений, по крайней мере, в более крупных проектах, но я не думаю о ведении журнала или трассировке как отладочном коде, поэтому я попросил разъяснений.Будьте последовательны, и не важно, какой. Также, если по какой-то причине вы должны взаимодействовать с другой программой или инструментом, используя определенный идентификатор DEBUG, это легко сделать.
источник
К сожалению
DEBUG
сильно перегружен. Например, рекомендуется всегда генерировать и сохранять файл pdb для сборок RELEASE. Что означает один из-Zx
флагов и-DEBUG
вариант компоновщика. Хотя_DEBUG
относится к специальным отладочным версиям библиотеки времени выполнения, таким как вызовыmalloc
иfree
. ТогдаNDEBUG
отключим утверждения.источник