问题 为什么NDEBUG而不是RELEASE?


宏时禁用标准C断言宏 NDEBUG 已定义,表示“未调试”。这导致了非常糟糕的双重否定案例 #ifndef NDEBUG //DebuggingCode #endif。似乎RELEASE本来是一个更好的术语选择,但我无法相信标准委员会会这样做而没有任何理由这样做....


5077
2018-02-10 15:16


起源

我发现在DEBUG和NDEBUG之间切换非常容易。 - Jim Rhodes
NDEBUG 只是暗示 没有调试。 RELEASE 可能意味着更多。 - cnicutar
“Debug”/“not debug”对于几乎所有的编程环境都有一定的意义。 “发布”/“发布软件”/“发布”是在您选择编译器标志后很长一段时间内发生的完全不同的对话。 - CB Bailey
#if defined(RELEASE)  #define NDEBUG  #else  #undef NDEBUG  #endif - pmg
@pmg:是的,我可以自己做这些事。我不是在抱怨事物的状态;我想弄清楚为什么做出决定以便我可以学习东西(例如我是否应该在我自己的编译标志中重用类似的策略) - Billy ONeal


答案:


有一个宏RELEASE意味着代码已准备好分发 - 当它可能没有时。另一方面,NDEBUG意味着调试已完成,因此可以进行测试。

我还认为,不得不关闭事情比确保你已经完成所有事情更好。这就是为什么大多数操作系统(例如)在很多人不需要的时候开启大部分操作系统的原因。

只是我谦虚的想法。


5
2018-02-10 15:22





NDEBUG 如何控制 assert 表现。

您通常不应该将它用于其他任何事情。如果您将其用于其他内容,例如额外的调试跟踪输出,则您无法在没有此额外代码的情况下构建应用程序,但启用了断言。

我建议您定义自己的预处理器符号,比如MY_TRACE,然后使用它。另外,将其定义为 0 要么 1 并使用 #if MY_TRACE。这样,如果将编译器配置为在预处理器表达式中使用未初始化的变量时发出警告,则可以使用符号捕获文件而不进行正确初始化。


6
2018-02-10 15:29



我为什么不把它用于其他任何事情? - Billy ONeal
好吧,如果你不把它用于其他任何事情,除了控制 assert,你永远不需要写 #ifndef NDEBUG。 - Lindydancer
当你需要离开时会发生什么 asserts能够追踪罕见的难以重现的错误,但是不希望在整个地方喷出数千行调试输出? - R..
@R。好点子。 Ladydancer:也好点。两者都是+1 - Billy ONeal
为什么不呢 NASSERT 然后...? NDEBUG 对我说“没有调试”。恕我直言 NDEBUG 应该涵盖应用程序中的所有调试输出。然后,如果您愿意,可以使用额外的宏 打开 somethig special。定义“1000”非标准宏以摆脱自定义调试级别看起来不方便...... - doc


我无法相信标准委员会会选择使用NDEBUG这个名称来控制 assert()没有理由这样做......

我只能猜测,但我怀疑预先标准可能已经有各种不同的名称用来控制断言宏如何工作,委员会可能决定选择一个不太可能被使用的“中性”名称在现有代码中出于某些无关的原因。我认为这可能是相当普遍的 RELEASE 在一些代码中用作宏,所以使用该名称(或 DEBUG)来控制 assert() 宏可能会导致冲突(特别是对于那些可能需要对断言进行精细控制的用户,仅针对部分代码启用它们)。


3
2018-02-11 08:17





作为长期的埃菲尔用户,我可以告诉你它以不同的方式使用,然后调试/ nodebug。正如所指出的,唯一的影响是禁用断言语句。 assert的目的是添加前后条件检查。建议大量使用它,它可能会使程序的性能降低10倍或更多。这被称为(穷人)合同设计。

当使用NDEBUG时,它并不意味着你完成了调试,只是它删除了这个繁重的调试工具。

遗憾的是,流行的调试/发布不是实际开发中的最佳案例,因为有充分的理由,你有一个Alpha,Beta,Release版本。

在alpha软件中,如果没有NDEBUG和调试器符号就可以编译它。 Beta使用NDEBUG集和调试器符号进行编译(并且可能已经使用优化开关),然后使用NDEBUG和完全优化编译最终版本。


0
2018-02-17 03:41