【问题标题】:Is assert(false) ignored in release mode?在发布模式下是否忽略了 assert(false)?
【发布时间】:2008-11-06 22:01:32
【问题描述】:

我正在使用 VC++。 assert(false) 在发布模式下会被忽略吗?

【问题讨论】:

    标签: c++ visual-c++ posix assert


    【解决方案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))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-04-13
            • 1970-01-01
            • 1970-01-01
            • 2018-05-15
            • 2015-02-18
            • 2016-05-10
            • 2012-09-16
            相关资源
            最近更新 更多