为什么让assert
宏只在调试配置中做一些有用的事情是一种常见的做法?如果它存在以测试不变量并检测编码错误,那么继续在生产软件中做同样的繁荣会不会更容易吗?
我有一些S60背景,存在__ASSERT_ALWAYS
和__ASSERT_DEBUG
,其中后者相当于assert
。
答案 0 :(得分:11)
对于应该永远不会发生的内容进行断言,即如果它确实存在,则需要修复代码中的错误。发布版本是"假设"没有错误,并且使用断言为用户查杀应用程序与任何其他错误行为一样糟糕。
答案 1 :(得分:7)
检查断言费用。您可能不希望在最终产品中存在额外的操作。如果断言总是会起作用,那么人们就会开始使用它们而不是“不要杀死性能”。相信我,有一个很多的人认为额外的检查性能杀死并会避免它。这些人实际上必须使用断言更多!
更重要的原因是,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
中。如果不是,那就是一个bug。但是,如果删除断言,修复x.stage
并继续前进,则希望错误不是那么严重。在这种情况下,最终用户实际上可以继续工作而不会注意到这一点。如果您也将assert
保持在发布模式,那么您将强制该人退出一个没有任何明显效果的错误。
实际上,您会随时获得软件的更新,声称他们已经修复了错误。其中一些,确实是assert
会遇到的错误。但是,作为最终用户,您没有遇到任何问题,并且因为assert
而未被打断而感到高兴,不是吗?
答案 2 :(得分:5)
我认为这是一种文化事物。支持在生产代码中删除此类检查的论据如下:
反对运行的参数如下
就个人而言,我运送的软件完全按照它的测试,断言和所有方式构建。但是,很大程度上取决于您的客户群以及您希望如何安排发布......
本文值得一读: - http://www.martinfowler.com/ieeeSoftware/failFast.pdf
但是当您将软件部署到客户时呢?我们没有 希望应用程序崩溃只是因为有一个错字 配置文件。对这种恐惧的一种反应是禁用断言 在现场。
不要那样做!请记住,发生错误 客户的网站通过您的测试过程。你可能会 难以复制它。这些错误是最难找到的,并且 一个很好的断言解释这个问题可以节省你几天 努力。
另一件事 - 在C ++中,使用BOOST_ASSERT可以将其设置为在断言失败时引发异常,这使得处理和可能从断言失败中恢复更加有用。我们将此与MadExcept结合使用,以便用户可以轻松地将字段中的任何断言失败发布到我们的错误跟踪器中,具有完整的调用堆栈,屏幕截图,无论如何。
答案 3 :(得分:1)
assert
除非您明确将其关闭,否则无效。 (通常)没有
有理由关闭它,即使在“发布”版本中,以及大多数
已发布的已发布的代码已激活assert
。
关闭它的主要原因是性能。在这种情况下,你 在性能所在的函数中非常本地关闭它 关键,如:
#ifdef TURNOFFCRITICALASSERTS
#define NDEBUG
#include <assert.h>
#endif
// Function with critical code here...
#undef NDEBUG
#include <assert.h>
这是C标准委员会设计assert
的方式。
通常,您不应该在本地定义NDEBUG
,就像这样。