为什么使用NDEBUG而不是RELEASE?

14

当宏NDEBUG被定义为"非调试"时,标准C assert 宏将被禁用。这会导致双重否定的情况,例如#ifndef NDEBUG //DebuggingCode #endif。看起来"RELEASE"可能是更好的选择,但我不相信标准委员会没有理由这样做....


我发现在DEBUG和NDEBUG之间切换非常容易。 - Jim Rhodes
10
NDEBUG指的是无调试RELEASE可能意味着更多。 - cnicutar
1
“调试”/“非调试”对于几乎所有编程环境都有一定的意义。“发布”/“发布软件”/“制作发布版”是一个完全不同的谈话,它发生在你选择编译器标志很久之后。 - CB Bailey
#if defined(RELEASE) #define NDEBUG #else #undef NDEBUG #endif - pmg
1
@pmg:是的,我自己可以做这样的事情。我并不在抱怨现状;我在努力弄清为什么做出了这个决定,以便我能够学到东西(例如,如果我应该在自己的编译标志中重复类似的策略)。 - Billy ONeal
4个回答

7

NDEBUG宏控制assert的行为。

通常情况下,不应将其用于其他任何事情。如果您将其用于其他事情(如额外的调试跟踪输出),则无法选择构建没有此额外代码但启用断言的应用程序选项。

我建议您定义自己的预处理器符号,例如MY_TRACE,并使用它。还要将其定义为01,并使用#if MY_TRACE。这样,如果您配置编译器在预处理器表达式中使用未初始化变量时发出警告,就可以捕获使用该符号但未正确初始化的文件。


1
为什么我不能将它用于其他任何事情? - Billy ONeal
5
如果你只是用它来控制 assert,那么你永远不需要编写 #ifndef NDEBUG - Lindydancer
2
当你需要启用assert来追踪一个罕见的难以复现的错误,但又不想在各个地方输出成千上万行的调试信息时,该怎么办? - R.. GitHub STOP HELPING ICE
3
为什么不用 NASSERT 呢?NDEBUG 对我来说意味着“没有调试”。在我看来,NDEBUG 应该包括应用程序中的所有调试输出。然后,如果您想要打开某些特殊的输出,可以使用额外的宏。定义一千个非标准宏来摆脱自定义的调试级别似乎不是很方便... - mip

6

具有宏释放(RELEASE)意味着代码已准备好分发,但实际上可能没有准备好。另一方面,NDEBUG则意味着调试已完成,因此可以进行测试。

我还认为关闭某些功能比确保打开所有功能要好。这就是为什么大多数操作系统(例如)在许多人不需要时都开启了大部分功能的原因。

以上仅是我的个人想法。


3
我无法相信标准委员会在没有理由的情况下会选择使用"NDEBUG"来控制"assert()"。 我只能猜测,在标准化之前,可能有多个实现使用不同的名称来控制断言宏的工作方式,委员会可能决定选择一个“中立”的名称,这个名称在现有代码中不太可能被用于其他目的。我认为,使用"RELEASE"作为宏在相当多的代码中是比较常见的,因此使用该名称(或"DEBUG")来控制"assert()"宏可能会导致冲突(特别是对于那些可能希望对断言进行精细控制的用户,仅在代码的某些部分打开它们)。

0
作为长期使用Eiffel的用户,我可以告诉你它的使用方式与debug/nodebug不同。正如指出的那样,唯一的影响是禁用assert语句。assert的目的是添加前置和后置条件检查。强烈建议经常使用它,但它可能会使程序的性能下降10倍或更多。这被称为(穷人的)契约式设计。
当使用NDEBUG时,并不意味着你已经完成了调试,只是这种重度调试工具被移除了。
流行的Debug/Release在实际开发中并不是最佳情况,因为你实际上有Alpha、Beta、Release发布模型的充分理由。
在alpha软件中,存在很多错误,因此您需要编译时不使用NDEBUG和调试符号。Beta版本则使用NDEBUG设置和调试符号(也许已经使用了优化开关),最终版本则使用NDEBUG和完全优化进行编译。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接