C/C++ 中宏 NDEBUG 的作用

  2022 年 05 月 04 日   C++  

NDEBUG 的作用主要是调整 assert 宏函数的行为。

1. assert 宏函数简介

这个函数的声明定义在 cassert 头文件(C 语言中是 assert.h):

void assert (int expression);

在程序运行的时候,如果表达式 expression 的估值结果为零(即表达式是 false),则一个错误信息会被输出到标准错误中,并且调用 abort() 将程序中止。如代码:

assert(("one equals two", 1 == 2));

:这里使用 comma operator,目的是为了在表达式中嵌入一个说明字符串,能够被打印出来,帮助程序员理解错误原因。

在运行的时候会输出:

a.out: main.cpp:16: int main(): Assertion `("one equals two", 1 == 2)' failed.

2. NDEBUG 的作用

assert 的定义代码一般是:

#ifdef NDEBUG
#define assert(condition) ((void)0)
#else
#define assert(condition) /*implementation defined*/
#endif

也就是说,assert 的行为取决于一个宏 NDEBUG 是否被定义了:

3. CMake 会隐式地定义 NDEBUG

如果将 CMake 的全局变量 CMAKE_BUILD_TYPE 设置为 Release,那么 CMake 会给编译器增加编译选项 -DNDEBUG

4. 结论

assert 是被设计用来检测程序员编程时错误的,而不是程序用户的运行时错误,因为程序用户在运行这个程序的时候,这个程序一般都是以 Release 模式编译的,也就是定义了 NDEBUG 宏。

参考

  1. assert - C++ Reference (cplusplus.com)
  2. assert - cppreference.com
  3. c - Does CMAKE_BUILD_TYPE=Release imply -DNDEBUG? - Stack Overflow