是采用C ++不好的做法,断言()?(Is using assert() in C++ bad pr

2019-06-27 05:28发布

我倾向于大量断言添加到我的C ++代码,使调试更容易在不影响发布版本的性能。 现在, assert是纯C宏没有C ++记机制设计。

C ++,另一方面限定std::logic_error ,这是指在存在于该程序的逻辑错误(由此得名)的情况下,以被抛出。 抛出一个实例可能是个完美的,更多的C ++十岁上下的替代assert

的问题是, assertabort都立即终止程序,而无需调用析构函数,因此跳过清理,而抛出异常手动增加了不必要的运行时成本。 解决此问题的方法就是建立一个自己的断言宏SAFE_ASSERT ,它的工作原理就像C语言的,但抛出失败异常。

我能想到的对这个问题三点意见:

  • 坚持到C的断言。 由于该程序将立即终止,也无所谓是否更改正确展开。 此外,使用#define在C ++ s是一样糟糕。
  • 抛出一个异常,并抓住它在main()。 允许代码跳过析构函数在程序中的任何状态是不好的做法,必须不惜一切代价避免,所以是呼叫终止()。 如果抛出异常,它们必须被捕获。
  • 抛出一个异常,让它终止程序。 异常终止的程序是好的,并且由于NDEBUG ,这永远不会在发布版本发生。 捕是不必要的,并且暴露的内部代码的实现细节以main()

是否有一个明确的答案,这个问题吗? 任何专业的参考?

编辑:析构函数跳绳是,当然,没有未定义的行为。

Answer 1:

断言是在C ++代码完全适当的。 异常和其他错误处理机制是不是真的打算为同样的事情断言。

错误处理是当有回收或很好的报告错误给用户的潜力。 例如,如果有想读你可能想要做的东西输入文件的错误。 错误可能会导致错误,但也可能仅仅是一个给定的输入适当的输出。

断言是对于像检查,当API通常不会被检查,或检查的事情开发商认为他是通过建设保证了API的要求得到满足。 例如,如果一个算法需要排序输入你通常不会检查的,但你可能有一个断言,以检查它,以便调试版本标志那种错误的。 断言应该总是指示操作不正确的程序。


如果你正在写一个程序,不正常关机可能会导致一个问题,那么你可能希望避免断言。 未定义行为严格C ++语言没有资格作为这里这样的问题,因为打一个断言来讲可能已经未定义行为,或违反这可以防止正常工作的一些清理一些其他要求的结果。

此外,如果你在一个异常的条款,然后它可能被捕获并“处理”尽管这违背了断言的根本目的实现断言。



Answer 2:

  • 断言是用于调试 。 你的出厂编号,用户不应该看到它们。 如果断言被击中,你的代码需要修复。

  • 例外情况是特殊情况 。 如果遇到一个,用户将不能够做自己想要的东西,但也许能恢复别处。

  • 错误处理是正常的程序流程。 例如,如果您提示用户输入一个数字,得到的东西不可分析,这是正常的 ,因为用户输入是不是你的控制之下,必须始终处理所有可能的情况是理所当然的事。 (如循环,直到你有一个有效的输入,说:“对不起,请重试”之间。)



Answer 3:

断言可以使用之前还是有些方法等的执行之后验证内部实现不变量,如内部状态。如果断言失败它的真正含义程序的逻辑被打破,你不能从此一蹶不振。 在这种情况下,你能做的最好是尽快打破不经过异常给用户。 什么是非常好的关于断言(至少在Linux上)是核心转储作为进程终止而产生的,因此,你可以很容易地调查堆栈跟踪和变量。 这是更为有用的了解比异常消息的逻辑错误。



Answer 4:

不运行析构函数,由于阿灵中止()不是不确定的行为!

如果是这样,那么这将是未定义行为调用std::terminate()也一样,所以这将是点提供呢?

assert()仅仅是在C作为有用++为C.断言是不是错误处理,他们为立即中止该程序。



Answer 5:

恕我直言,断言是检查条件如有违反,让一切废话。 因此,你不能从中恢复,或者更确切地说,恢复是无关紧要的。

我会组分为2类:

  • 开发者的罪(如返回负值的概率函数):

浮动概率(){返回-1.0; }

断言(概率()> 0.0)

  • 机器坏了(例如,它运行你的程序的机器是非常错误的):

INT X = 1;

断言(X> 0);

这些都是微不足道的例子,但不脱离现实太远。 例如,想想返回负指标与载体使用天真的算法。 或嵌入到定制的硬件方案。 或者说,因为还是发生了

如果有这样的发展错误,你不应该有信心实现的任何恢复或错误处理机制。 这同样适用于硬件错误。



文章来源: Is using assert() in C++ bad practice?