Відповіді:
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буде відключено твердження.