Відповіді:
Visual Studio визначає, _DEBUG
коли ви вказуєте параметр /MTd
або /MDd
параметр, NDEBUG
відключає стандартні твердження C. Використовуйте їх, коли це доречно, тобто _DEBUG
якщо ви хочете, щоб ваш код налагодження відповідав методикам налагодження MS CRT і NDEBUG
якщо ви хочете відповідати assert()
.
Якщо ви визначаєте свої власні макроси налагодження (і ви не зламаєте компілятор або C виконання), уникайте запуску імен із підкресленням, оскільки вони зарезервовані.
Чи стандарт NDEBUG?
Так, це стандартний макрос із семантичним "Not Debug" для стандартів C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014. У _DEBUG
стандартах немає макросів.
Стандарт C ++ 2003 надсилає зчитувач на "сторінку 326" на "17.4.2.1 заголовки" до стандарту C.
Цей NDEBUG подібний, оскільки це те саме, що і бібліотека Standard C.
У C89 (програмісти C назвали цей стандарт як стандарт С) у розділі "4.2 ДІАГНОСТИКА" було сказано
http://port70.net/~nsz/c/c89/c89-draft.html
Якщо NDEBUG визначений як ім'я макросу в точці вихідного файлу, куди він включений, макрос затвердження визначається просто як
#define assert(ignore) ((void)0)
Якщо подивитися на значення _DEBUG
макросів у Visual Studio
https://msdn.microsoft.com/en-us/library/b0084kay.aspx,
то буде видно, що цей макрос автоматично визначається вашим вибором бібліотечної версії бібліотеки часу виконання.
Я покладаюсь на це NDEBUG
, тому що це єдиний, поведінка якого стандартизовано серед компіляторів та реалізацій (див. Документацію до стандартного макросу assrt). Негативна логіка - це невелика швидкість зчитування, але це загальна ідіома, до якої можна швидко адаптуватися.
Покладатися на щось подібне _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
, сильно перевантажений. Наприклад, рекомендується завжди генерувати та зберігати pdb-файл для RELEASE-збірок. Що означає один із -Zx
прапорів і -DEBUG
параметр linker. Хоча _DEBUG
стосується спеціальних версій налагодження бібліотеки виконання, таких як дзвінки до malloc
та free
. Потім NDEBUG
буде відключено твердження.