_DEBUG与NDEBUG

哪个预处理器定义应该用于指定代码的debugging部分?

使用#ifdef _DEBUG#ifndef NDEBUG还是有更好的方法来做,例如#define MY_DEBUG

我觉得_DEBUG是Visual Studio特定的,是NDEBUG标准吗?

Visual Studio在指定/MTd/MDd选项时定义_DEBUGNDEBUG禁用标准C断言。 如果希望debugging代码与MS CRTdebugging技术保持一致,并且如果要与assert()保持一致,则使用NDEBUG

如果你定义了你自己的debuggingmacros(而且你没有破解编译器或者C运行库),那么避免用下划线开始名字,因为这些是保留的。

我依赖NDEBUG ,因为它是唯一一个在编译器和实现中标准化的行为(请参阅标准断言macros的文档)。 负面的逻辑是一个小的可读性减速块,但这是一个可以快速适应的常见习惯用法。

依赖像_DEBUG这样的东西,将依赖于特定编译器和库实现的实现细节。 其他编译器可能会也可能不会select相同的约定。

第三个选项是为你的项目定义自己的macros,这是相当合理的。 拥有自己的macros可以让你跨越实现进行移植,并允许你独立于断言来启用或者禁用你的debugging代码。 但是,一般来说,我build议不要在编译时启用不同类的debugging信息,因为这会导致为构build(和testing)构build的configuration数量增加,而这种configuration的数量可能有限。

有了这些选项,如果您使用第三方代码作为您的项目的一部分,您将必须知道它使用哪种约定。

是NDEBUG标准?

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

C ++ 2003标准在“17.4.2.1 Headers”的“第326页”处将阅读器发送到标准C.

该NDEBUG类似于这与标准C库相同。

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

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

如果将NDEBUG定义为包含源文件中的macros名称,则assertmacros定义为

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

如果在Visual Studio https://msdn.microsoft.com/en-us/library/b0084kay.aspx中查看;_DEBUGmacros的含义,就会看到这个macros是由你的语言运行库版本的сhoice自动定义的。

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

在我看来,这与其他任何debugging都是分开的 – 所以我使用NDEBUG以外的东西来控制程序中的debugging信息。 我所使用的不同,取决于我正在使用的框架; 不同的系统有不同的启用macros,我使用任何适当的。

如果没有框架,我会用一个没有前导下划线的名字; 那些往往被保留到'执行',我试图避免与名称collsions的问题 – 加倍,所以当名称是一个macros。

保持一致,哪一个并不重要。 此外,如果由于某种原因,您必须使用某个DEBUG标识符与另一个程序或工具进行交互,这很容易做到

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

不幸的是,“DEBUG”重载了很多。 例如,build议始终生成并保存用于RELEASE构build的pdb文件。 这意味着其中一个-Zx标志和-DEBUG链接器选项。 而_DEBUG涉及运行时库的特殊debugging版本,例如调用malloc和free。 然后NDEBUG将禁用断言。