在发布模式下是不是忽略了 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)?的主要内容,如果未能解决你的问题,请参考以下文章

TestNg的忽略测试和超时测试

C++ assert(0); 语句直接忽略了,没有执行,可能是啥原因啊?各位大虾,帮帮忙

Q_ASSERT 发布构建语义

Java 之 assert (断言)

GoogleTest:CLang 错误编译 ASSERT_FALSE(false)

C 标准库系列之assert.h