_DEBUG与NDEBUG

def*_*ode 132 c c++ debugging

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

使用#ifdef _DEBUG或者#ifndef NDEBUG是否有更好的方法来做到这一点,例如#define MY_DEBUG

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

Chr*_*oph 108

Visual Studio定义_DEBUG何时指定/MTd/MDd选项,NDEBUG禁用标准C断言.在适当的时候使用它们,即_DEBUG如果您希望您的调试代码与MS CRT调试技术一致,并且NDEBUG您希望与之保持一致assert().

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

  • +1.特别是允许NDEBUG在单个TU中#undef'd和#define'd(并重新包含<assert.h>相应地更改断言宏).因为这与预期/期望不同,所以通常使用另一个宏来控制"编译范围"的调试标志,正如这个答案所说的那样. (17认同)
  • 显然,是编译器本身定义了这些宏,而不是 Visual Studio(IDE)。非常感谢您的回答! (3认同)

Adr*_*thy 43

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

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

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

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


bru*_*iuz 40

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)
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*ler 13

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

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

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

  • 即使我没有在代码中编译其他调试或跟踪工具,我仍保持声明处于活动状态.断言识别不可能的情况.一般跟踪和调试是IMO完全独立的. (4认同)
  • @AdrianMcCarthy:如果启用了所有调试,则可能导致程序缓慢运行.因此,对调试类型进行分类是很常见的,并允许人们单独启用/禁用它们.MSVC有两个或三个用于启用/禁用标准库的各种调试,如std :: vector. (2认同)
  • @MooingDuck:是的,一些调试代码可能会变慢.在这种情况下,你_might_想要一种方法来控制慢速代码是否独立于平凡的检查运行.但这与将断言放在一个类别和`#if`控制的代码在另一个类别中的情况不同.`assert(huge_object.IsValid());```assert(ptr!= nullptr)可能很慢;`可能不是.我同意Jonathan的观点,_logging_和_tracing_应该与断言不同,至少在大型项目中是这样,但我不认为_logging_或_tracing_是调试代码,这就是我要求澄清的原因. (2认同)

Ear*_*rlz 6

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

#ifdef THEIRDEBUG
#define MYDEBUG
#endif //and vice-versa
Run Code Online (Sandbox Code Playgroud)


小智 5

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