_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
How to Use Break to Exit Multiple Nested 'For' Loops
How Is "=Default" Different from "{}" for Default Constructor and Destructor
Is Pass-By-Value a Reasonable Default in C++11
Differences Between Unique_Ptr and Shared_Ptr
Copying a Polymorphic Object in C++
Should the Trailing Return Type Syntax Style Become the Default For New C++11 Programs
How to Use a C++ String in a Structure When Malloc()-Ing the Same Structure
How to Properly Use Namespaces in C++
What Are the Differences Between .So and .Dylib on Macos
How Does Photoshop Blend Two Images Together
Differences Between C++ String == and Compare()
Are Exceptions in C++ Really Slow
The Program Can't Start Because Libgcc_S_Dw2-1.Dll Is Missing
How to Avoid Memory Leaks When Using a Vector of Pointers to Dynamically Allocated Objects in C++