deft_code
deft_code

Reputation: 59299

_DEBUG vs NDEBUG

Which preprocessor define should be used to specify debug sections of code?

Use #ifdef _DEBUG or #ifndef NDEBUG or is there a better way to do it, e.g. #define MY_DEBUG?

I think _DEBUG is Visual Studio specific, is NDEBUG standard?

Upvotes: 186

Views: 224775

Answers (7)

Mecki
Mecki

Reputation: 133019

Despite the name, NDEBUG has nothing to do if you are creating a debug build or not, it controls whether assertions (assert()) are active or not. I would not base anything else on it, as you may want to have debug builds without assertions or release builds with assertions from time to time and then you must set NDEBUG accordingly but that doesn't mean you also want all other code to be debug or release code.

From the perspective of compilers, there is not such thing as a debug build. You tell the compiler to build code with a specific set of settings and if you want to use different settings for different kinds of builds, then this is something you actually made up yourself and the compiler knows nothing about that. You may actually have 50 different build styles and not just release and debug (profile, test, deploy, etc.), so it's up to you how these styles are identified in your own code. If you need pre-processor tags for these, you define how those are named and the same name space rules applies as for everything else you'd define in your code.

Upvotes: 2

Konstantin Burlachenko
Konstantin Burlachenko

Reputation: 5675

Is NDEBUG standard?

Yes it is a standard macro with the semantic "Not Debug" for C89, C99, C++98, C++2003, C++2011, C++2014 standards. There are no _DEBUG macros in the standards.

C++2003 standard send the reader at "page 326" at "17.4.2.1 Headers" to standard C.

That NDEBUG is similar as This is the same as the Standard C library.

In C89 (C programmers called this standard as standard C) in "4.2 DIAGNOSTICS" section it was said

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

If NDEBUG is defined as a macro name at the point in the source file where <assert.h> is included, the assert macro is defined simply as

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

If look at the meaning of _DEBUG macros in Visual Studio https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros then it will be seen, that this macro is automatically defined by your сhoice of language runtime library version.

Upvotes: 90

Jonathan Leffler
Jonathan Leffler

Reputation: 754110

The macro NDEBUG controls whether assert() statements are active or not.

In my view, that is separate from any other debugging - so I use something other than NDEBUG to control debugging information in the program. What I use varies, depending on the framework I'm working with; different systems have different enabling macros, and I use whatever is appropriate.

If there is no framework, I'd use a name without a leading underscore; those tend to be reserved to 'the implementation' and I try to avoid problems with name collisions - doubly so when the name is a macro.

Upvotes: 27

James
James

Reputation: 51

Unfortunately DEBUG is overloaded heavily. For instance, it's recommended to always generate and save a pdb file for RELEASE builds. Which means one of the -Zx flags, and -DEBUG linker option. While _DEBUG relates to special debug versions of runtime library such as calls to malloc and free. Then NDEBUG will disable assertions.

Upvotes: 5

Christoph
Christoph

Reputation: 169623

Visual Studio defines _DEBUG when you specify the /MTd or /MDd option, NDEBUG disables standard-C assertions. Use them when appropriate, ie _DEBUG if you want your debugging code to be consistent with the MS CRT debugging techniques and NDEBUG if you want to be consistent with assert().

If you define your own debugging macros (and you don't hack the compiler or C runtime), avoid starting names with an underscore, as these are reserved.

Upvotes: 151

Adrian McCarthy
Adrian McCarthy

Reputation: 47982

I rely on NDEBUG, because it's the only one whose behavior is standardized across compilers and implementations (see documentation for the standard assert macro). The negative logic is a small readability speedbump, but it's a common idiom you can quickly adapt to.

To rely on something like _DEBUG would be to rely on an implementation detail of a particular compiler and library implementation. Other compilers may or may not choose the same convention.

The third option is to define your own macro for your project, which is quite reasonable. Having your own macro gives you portability across implementations and it allows you to enable or disable your debugging code independently of the assertions. Though, in general, I advise against having different classes of debugging information that are enabled at compile time, as it causes an increase in the number of configurations you have to build (and test) for arguably small benefit.

With any of these options, if you use third party code as part of your project, you'll have to be aware of which convention it uses.

Upvotes: 60

Earlz
Earlz

Reputation: 63845

Be consistent and it doesn't matter which one. Also if for some reason you must interop with another program or tool using a certain DEBUG identifier it's easy to do

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

Upvotes: 8

Related Questions