_DEBUG与NDEBUG

时间:2010-02-18 16:59:38

标签: c++ c debugging

应该使用哪个预处理器定义来指定代码的调试部分?

使用#ifdef _DEBUG#ifndef NDEBUG或者有更好的方法,例如#define MY_DEBUG

我认为_DEBUG是Visual Studio特有的,是NDEBUG标准吗?

6 个答案:

答案 0 :(得分:106)

当您指定_DEBUG/MTd选项时,Visual Studio定义/MDdNDEBUG禁用标准C断言。如果您希望调试代码与MS CRT debugging techniques_DEBUG一致,如果您希望与NDEBUG保持一致,请在适当时使用它们,即assert()

如果您定义自己的调试宏(并且不破解编译器或C运行时),请避免使用下划线开始名称,因为这些是保留的。

答案 1 :(得分:39)

我依赖NDEBUG,因为它是唯一一个在编译器和实现之间标准化的行为(请参阅标准断言宏的文档)。负逻辑是一个小的可读性speedbump,但它是你可以快速适应的常用习惯。

依赖于_DEBUG之类的东西将依赖于特定编译器和库实现的实现细节。其他编译器可能会也可能不会选择相同的约定。

第三个选项是为您的项目定义自己的宏,这是非常合理的。拥有自己的宏可以实现跨实现的可移植性,它允许您独立于断言启​​用或禁用调试代码。虽然,一般来说,我建议不要在编译时启用不同类别的调试信息,因为它会导致您必须构建(和测试)的配置数量增加,这可能会带来很小的好处。

使用这些选项中的任何一个,如果您将第三方代码用作项目的一部分,则必须了解它使用的约定。

答案 2 :(得分:36)

  

NDEBUG标准吗?

是的,它是C89,C99,C ++ 98,C ++ 2003,C ++ 2011,C ++ 2014标准的语义“Not Debug”的标准宏。标准中没有_DEBUG个宏。

C ++ 2003标准发送阅读器“第326页”“17.4.2.1标题” 标准C.

  

NDEBUG类似,因为它与标准C库相同。

在C89(C程序员将此标准称为标准C)中的“4.2诊断”一节中有人说

  

http://port70.net/~nsz/c/c89/c89-draft.html

     

如果NDEBUG被定义为源文件中的宏名称   在包含的地方,断言宏被简单地定义为

     #define assert(ignore) ((void)0)

如果在Visual Studio中查看_DEBUG宏的含义 https://msdn.microsoft.com/en-us/library/b0084kay.aspx 然后可以看出,这个宏是由你的语言运行时库版本自动定义的。

答案 3 :(得分:13)

宏NDEBUG控制assert()语句是否处于活动状态。

在我看来,这与其他任何调试都是分开的 - 所以我使用NDEBUG以外的东西来控制程序中的调试信息。根据我正在使用的框架,我使用的内容各不相同;不同的系统有不同的启用宏,我使用任何适当的。

如果没有框架,我会使用没有前导下划线的名称;那些往往被保留给'实现',我试图避免名字collsions的问题 - 当名称是一个宏时,加倍。

答案 4 :(得分:6)

保持一致,哪一个无关紧要。此外,如果由于某种原因你必须使用某个DEBUG标识符与另一个程序或工具互操作,那么很容易做到

#ifdef THEIRDEBUG
#define MYDEBUG
#endif //and vice-versa

答案 5 :(得分:3)

不幸的是“DEBUG”严重超载。例如,建议始终为RELEASE构建生成并保存pdb文件。这意味着-Zx标志之一和-DEBUG链接器选项。而_DEBUG与运行时库的特殊调试版本有关,例如对malloc和free的调用。然后NDEBUG将禁用断言。