简体   繁体   中英

The #define NDEBUG doesn't seem to work

I read in a text that placing the following preprocessor line ignores all the subsequent assert preprocessor directives. But this doesn't seem to work and the assert statement infact is processed by the preprocessor and aborts the program when the condition in the assert in not satisfied(I know the abort is a correct behaviour when the assert condition is not satisfied). My question is why is the assert statement not ignored by placing #define NDEBUG. The code is

#include<stdio.h>
#include<assert.h>
#define NDEBUG

int main(){
    int x = 0;

    assert (x!=0);  

}

Change the order of appearance, then it should work:

#define NDEBUG
#include<assert.h>

NDEBUG is used to define the assert() macro in <assert.h> conditionally.

Defines does not work like this. You should define your NDEBUG before including assert.h

This happening because inside assert.h NDEBUG is checked using #ifdef :

#ifdef  NDEBUG
# define assert(expr)           (__ASSERT_VOID_CAST (0))
#else
//....

NDEBUG has to appear before the header is included. This is exactly specified in the standard.

The header defines the assert and static_assert macros and refers to another macro,

  NDEBUG 

which is not defined by <assert.h> 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)** 

The assert macro is redefined according to the current state of NDEBUG each time that is included.

from N1570, emphasis mine.

All previous answers are correct.

But assert are not meant to be used by adding #define NDEBUG in the source code.

The canonical way:

1) Use #include <assert.h> and call assert() in your code.

2) Then at build time:

2a) gcc blablabla : this is a debug build, NDEBUG is not defined, and assert() goes into action.

2b) gcc blablabla -DNDEBUG blablabla : this is a production build, NDEBUG is defined, assert() does nothing.

Assertions are a way to spot errors/exceptional conditions at development time . The NDEBUG could be spelled as "NOT_DEBUG".

Another way, add definition in CMakeLists.txt sounds not bad.

set(release 1)

if (release)
    add_definitions(-DNDEBUG)
endif ()

just set(release 0) if you debug, and set(release 1) when release

It's more convenient and human-readable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM