_Debug VS Ndebug

_DEBUG vs NDEBUG

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.

Where are NDEBUG and _DEBUG Defined in Visual Studio 2015?

Generally these are defined as part of the additional pre processor defines/options and ultimately land up on the command line with a /D option switch.

Depending on the project configuration they could be inherited from a parent properties file so may not be immediately visible in the project.

The runtime switches /MD, /MT and the debug versions /MDd and /MTd define these as well; in particlar the _DEBUG. The MSDN documentation (here) for these provides more detail.

From experience, in the case of NDEBUG, it may be better to test #ifndef _DEBUG. I generally find that more consistent.

Use _DEBUG definition in other compilers then Visual Studio

When developing software for cross-platform compatibility, I usually prefer to explicitly pass the #define of _DEBUG to the compiler/toolchain.

Microsoft Visual C++ compiler already #defines it, but for GCC you can pass it using the -D commandline options, i.e.:

gcc -D _DEBUG ...

In case you use CMake as building tool (as I do), you can more easily add it to your CMakeLists.txt file:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")

What is the NDEBUG preprocessor macro used for (on different platforms)?

That is a decision up to the maintainer(s) of the framework in question. Since such decisions are subject to change, it's nothing you should rely on. I use NDEBUG as a toggle for everything debug-related (e.g. trace outputs), but I might change my mind in the next release. No answer anyone could give here is a replacement for checking the API documentation of the frameworks you use in a given project.

That being said, using NDEBUG in library / framework headers, for anything else but assert(), would be a rather dumb design decision. The application programmer is explicitly allowed to set / unset NDEBUG however he sees fit, before and / or after including the headers of any library or framework, so the lib / framework maintainer could not rely on NDEBUG being set for a release lib or not set for a debugging lib. I doubt any significant project would have relied on NDEBUG that way.

DEBUG vs _DEBUG

In your own code you can check for any macro you want, so it doesn't matter which one to use.

But the libraries you use may behave different. E.g. the MSDN documentation about assert states:

Assertion statements compile only when _DEBUG is defined. When _DEBUG is not defined, the compiler treats assertions as null statements.

So I would suggest to always use _DEBUG.

Edit: According to MSDN you do not even have to define any special debug macro because the compiler will do it for you as soon as you specify a debug runtime library.

Why NDEBUG instead of RELEASE?

Having a macro RELEASE implies that the code is ready for distribution - when it may not. NDEBUG on the other hand implies that debugging is complete, hence ready for testing.

I also suppose that having to turn things off is better than having to make sure that you have turned everything on. That is why most OSs (for example) have most things switched on when a lot of people do not need it.

Just my humble thoughts.

How to make DEBUG macros portable

I don't know the real reason for MS not using the NDEBUG macro, and defining the _DEBUG instead. My my guess is that it is related to the definition of _ASSERT instead of assert.

The problem with assert() is that the C standard defines requires it to print a line to the console and abort the program. But Windows programs don't usually have a console, so MS thought that it would be nice to pop up a window instead. But that assert() pops up a window would not be standard compliant, so the developed a similar but different macro:_ASSERT, and a different macro to control its behavior: _DEBUG.

A similar mess exists with the _UNICODE and UNICODE macros, but that's another story...

Note that in the default configuration of a Visual C++ project, in debug mode _DEBUG is defined, but NDEBUG is not. While in release mode _DEBUG is not defined, but NDEBUG is. So for your own code, you can use any one of them. But naturally, if you want to be portable you should use NDEBUG, as the _DEBUG name is reserved to the compiler implementation.



Related Topics



Leave a reply



Submit