NDEBUG 是 C++ 中一个预定义的宏,主要用于控制调试相关的代码。

主要作用

  • 控制 assert() 断言的行为
  • 当定义了 NDEBUG 宏时,assert() 语句会被完全忽略(编译器会将其优化掉)
  • 常用于区分 Debug 和 Release 构建模式

使用方式

// 方式1: 在代码中定义
#define NDEBUG  // 必须在 #include <assert.h> 之前定义
 
// 方式2: 编译时定义
// g++ -DNDEBUG program.cpp
// 或在 CMake 中设置

实际示例

#include <cassert>  // 或 <assert.h>
 
void divide(int a, int b) {
    // 在 Debug 模式下会检查,Release 模式下会被忽略
    assert(b != 0 && "Divisor cannot be zero!");
    
    // 正常的除法操作
    int result = a / b;
}
 
int main() {
    divide(10, 2);  // 正常执行
    divide(10, 0);  // Debug 模式下会触发断言失败
                    // Release 模式下会直接执行导致崩溃
}

最佳实践

// 可以基于 NDEBUG 实现自定义的调试功能
#ifndef NDEBUG
    #define DEBUG_LOG(x) std::cout << x << std::endl
#else
    #define DEBUG_LOG(x)  // Release 模式下成为空操作
#endif
 
void someFunction() {
    DEBUG_LOG("Function called");  // 只在 Debug 模式下打印
    // ... 函数实现
}

注意事项

  • assert 应该用于检查 ” 不应该发生 ” 的情况,而不是正常的错误处理
  • 不要在 assert 中包含有副作用的表达式,因为它们在 Release 模式下会被移除
  • 对于必须执行的检查,应使用正常的 if 语句而不是 assert

在大型项目中的应用

  • 可以创建多层次的调试宏
#ifndef NDEBUG
    #define VERIFY(x) assert(x)
#else
    #define VERIFY(x) (x)
#endif
 
// VERIFY 在任何模式下都会执行表达式
// 但只在 Debug 模式下进行断言检查