为什么断言宏仅用于调试构建

问题描述 投票:5回答:4

为什么这是使assert宏仅在调试配置中有用的常规做法?如果可以测试不变式和检测编码错误,那么继续进行生产软件的同样蓬勃发展,难道不是一件容易的事吗?

我有一些S60背景,并且存在__ASSERT_ALWAYS__ASSERT_DEBUG,后者等效于assert

c++ c debugging assert
4个回答
7
投票

检查断言费用。您可能不想在最终产品中进行额外的操作。如果断言总是奏效的,那么人们将开始减少使用它们以“不会破坏性能”。相信我,有很多人认为额外的检查是[[Performance kill]],他们会避免使用。这些是实际上必须更多使用断言的人!更重要的原因是,assert如果失败,只会中止您的程序。这对于最终用户毫无用处。如果要使程序实际上以一条消息终止或执行一些有用的操作,则必须编写自己的断言。在这种情况下,您当然也可以选择将其保持在发布模式。最后,断言可以帮助您发现错误,尤其是隐藏的错误,但是在软件执行过程中,它们实际上可能不会发生。想象以下代码:

struct X { // other stuff int stage; }; X x; ... do some stuff assert(x.stage == STAGE_2); x.stage = STAGE_3; // go to next stage ... do more stuff

在这样的示例中,您的逻辑说x应该在STAGE_2中。如果不是,那是一个错误。但是,如果删除断言,修复x.stage并继续进行,则希望该错误不太严重。在这种情况下,最终用户实际上可以继续工作而无需注意。如果您也将assert设置为发布模式,则将迫使该人员退出没有任何可见效果的错误。

实际上,您一直在获取软件更新,因为它们声称已修复了错误。其中一些确实是assert可能会发现的错误。但是,作为最终用户的您没有任何问题,实际上很高兴您没有因为这些assert而受到打扰,不是吗?

断言是为应该
从不发生]的内容而设计的,即,如果确实如此,则您的代码中有一个错误需要修复。发布是“应该”没有漏洞的构建,并且用断言为用户杀死应用程序与任何其他错误行为一样严重。

我认为这是文化上的事情。支持删除生产代码中这种检查的参数如下:

这会使您的代码运行速度变慢。

    它使最终的可执行文件更大。
  • 您的代码在发布后就不会出现错误。
  • 这将导致您的程序突然猛烈退出,并可能丢失数据。
  • 反对运行的论点如下
  • 您要交付您测试的

      exact
  • 代码。
  • 在现场报告的调试问题变得容易得多无论您想怎么想,您发布的代码
  • WILL
  • 都有错误
  • 性能和尺寸影响通常很小。
  • 快速失败可能比在程序处于不希望的状态时尝试继续执行更可取。
  • 我个人提供的软件完全按照经过测试,声明和所有的方式构建。但是,这在很大程度上取决于您的客户群以及您希望如何安排发布......>
  • 本文值得一读:-http://www.martinfowler.com/ieeeSoftware/failFast.pdf
  • 但是当您将软件部署给客户时呢?我们不希望应用程序崩溃只是因为配置文件。对这种恐惧的一种反应是禁用断言在现场。

    不要那样做!请记住,在客户的网站是通过您的测试过程完成的。你可能会复制它有麻烦。这些错误最难发现,并且适当说明问题的断言可以为您节省几天的时间努力。

    另一件事-在C ++中,您可以使用BOOST_ASSERT将其设置为在断言失败时引发异常,这使处理断言并可能从断言失败中恢复更加有用。我们将其与MadExcept结合使用,以便用户可以轻松地将字段中的任何断言故障发布到我们的错误跟踪器中,包括完整的调用堆栈,屏幕截图以及您所拥有的一切。

    assert起作用,除非您明确将其关闭。 (通常)没有甚至在“发布”版本中也要关闭它的原因,并且大多数我提供的已发布代码已激活assert
    关闭它的主要原因是性能。在这种情况下,您在性能很强的函数中非常本地地将其关闭关键,类似于:

    #ifdef TURNOFFCRITICALASSERTS #define NDEBUG #include <assert.h> #endif // Function with critical code here... #undef NDEBUG #include <assert.h>

    这是C标准委员会设计使用assert的方式。通常,不应该像这样在本地定义NDEBUG


    11
    投票
    从不发生]的内容而设计的,即,如果确实如此,则您的代码中有一个错误需要修复。发布是“应该”没有漏洞的构建,并且用断言为用户杀死应用程序与任何其他错误行为一样严重。

    5
    投票

    这会使您的代码运行速度变慢。


    1
    投票
    关闭它的主要原因是性能。在这种情况下,您在性能很强的函数中非常本地地将其关闭关键,类似于:

    #ifdef TURNOFFCRITICALASSERTS #define NDEBUG #include <assert.h> #endif // Function with critical code here... #undef NDEBUG #include <assert.h>

    © www.soinside.com 2019 - 2024. All rights reserved.