在发布模式下是不是忽略了 assert(false)?
Posted
技术标签:
【中文标题】在发布模式下是不是忽略了 assert(false)?【英文标题】:Is assert(false) ignored in release mode?在发布模式下是否忽略了 assert(false)? 【发布时间】:2008-11-06 22:01:32 【问题描述】:我正在使用 VC++。 assert(false)
在发布模式下会被忽略吗?
【问题讨论】:
【参考方案1】:如果在发布模式下编译包括定义NDEBUG,那么是的。
见assert (CRT)
【讨论】:
文档指出“断言例程在 C 运行时库的发布和调试版本中都可用。”不过看看 assert.h 头文件,在包含它之前定义 NDEBUG 肯定会导致 assert() 编译为无操作。但是,没有定义 NDEBUG 的发布模式代码完全有可能导致断言中止。我只是想澄清我自己的理解并分享我的发现。【参考方案2】:IIRC,assert(x) 是一个宏,在定义 NDEBUG 时计算结果为空,这是 Visual Studio 中发布版本的标准。
【讨论】:
【参考方案3】:assert 宏(至少它通常是一个宏)通常在发布代码中定义为无操作。它只会在调试代码中触发。话说回来。我曾在定义了自己的断言宏的地方工作过,它在调试和发布模式下都触发了。
我被教导将断言用于“永远”不会为假的条件,例如函数的前置条件。
【讨论】:
【参考方案4】:我认为只有定义了 NDEBUG(Visual C++ 应用程序默认使用它)。
【讨论】:
【参考方案5】:我认为过分依赖断言的确切行为是错误的。 "assert(expr)" 的正确语义是:
表达式 expr 可能会或可能不会被计算。 如果 expr 为真,则继续正常执行。 如果 expr 为 false,则发生的情况未定义。更多信息请访问http://nedbatchelder.com/text/assert.html
【讨论】:
ISO C 中描述了正确的语义。如果启用了断言(NDEBUG
在包含<assert.h>
之前未定义),那么如果assert
的控制表达式比较等于零,然后表达式的文本、文件和行号将打印在标准错误流上的一些实现定义的消息中。然后调用abort
函数。 (从 C99 开始,消息还需要包含函数名称。)【参考方案6】:
GNU 也一样:
#ifdef NDEBUG
# define assert(expr) (__ASSERT_VOID_CAST (0))
【讨论】:
以上是关于在发布模式下是不是忽略了 assert(false)?的主要内容,如果未能解决你的问题,请参考以下文章
C++ assert(0); 语句直接忽略了,没有执行,可能是啥原因啊?各位大虾,帮帮忙