我倾向于大量断言添加到我的C ++代码,使调试更容易在不影响发布版本的性能。 现在, assert
是纯C宏没有C ++记机制设计。
C ++,另一方面限定std::logic_error
,这是指在存在于该程序的逻辑错误(由此得名)的情况下,以被抛出。 抛出一个实例可能是个完美的,更多的C ++十岁上下的替代assert
。
的问题是, assert
和abort
都立即终止程序,而无需调用析构函数,因此跳过清理,而抛出异常手动增加了不必要的运行时成本。 解决此问题的方法就是建立一个自己的断言宏SAFE_ASSERT
,它的工作原理就像C语言的,但抛出失败异常。
我能想到的对这个问题三点意见:
- 坚持到C的断言。 由于该程序将立即终止,也无所谓是否更改正确展开。 此外,使用
#define
在C ++ s是一样糟糕。 - 抛出一个异常,并抓住它在main()。 允许代码跳过析构函数在程序中的任何状态是不好的做法,必须不惜一切代价避免,所以是呼叫终止()。 如果抛出异常,它们必须被捕获。
- 抛出一个异常,让它终止程序。 异常终止的程序是好的,并且由于
NDEBUG
,这永远不会在发布版本发生。 捕是不必要的,并且暴露的内部代码的实现细节以main()
是否有一个明确的答案,这个问题吗? 任何专业的参考?
编辑:析构函数跳绳是,当然,没有未定义的行为。
断言是在C ++代码完全适当的。 异常和其他错误处理机制是不是真的打算为同样的事情断言。
错误处理是当有回收或很好的报告错误给用户的潜力。 例如,如果有想读你可能想要做的东西输入文件的错误。 错误可能会导致错误,但也可能仅仅是一个给定的输入适当的输出。
断言是对于像检查,当API通常不会被检查,或检查的事情开发商认为他是通过建设保证了API的要求得到满足。 例如,如果一个算法需要排序输入你通常不会检查的,但你可能有一个断言,以检查它,以便调试版本标志那种错误的。 断言应该总是指示操作不正确的程序。
如果你正在写一个程序,不正常关机可能会导致一个问题,那么你可能希望避免断言。 未定义行为严格C ++语言没有资格作为这里这样的问题,因为打一个断言来讲可能已经未定义行为,或违反这可以防止正常工作的一些清理一些其他要求的结果。
此外,如果你在一个异常的条款,然后它可能被捕获并“处理”尽管这违背了断言的根本目的实现断言。
断言可以使用之前还是有些方法等的执行之后验证内部实现不变量,如内部状态。如果断言失败它的真正含义程序的逻辑被打破,你不能从此一蹶不振。 在这种情况下,你能做的最好是尽快打破不经过异常给用户。 什么是非常好的关于断言(至少在Linux上)是核心转储作为进程终止而产生的,因此,你可以很容易地调查堆栈跟踪和变量。 这是更为有用的了解比异常消息的逻辑错误。
不运行析构函数,由于阿灵中止()不是不确定的行为!
如果是这样,那么这将是未定义行为调用std::terminate()
也一样,所以这将是点提供呢?
assert()
仅仅是在C作为有用++为C.断言是不是错误处理,他们为立即中止该程序。
恕我直言,断言是检查条件如有违反,让一切废话。 因此,你不能从中恢复,或者更确切地说,恢复是无关紧要的。
我会组分为2类:
浮动概率(){返回-1.0; }
断言(概率()> 0.0)
- 机器坏了(例如,它运行你的程序的机器是非常错误的):
INT X = 1;
断言(X> 0);
这些都是微不足道的例子,但不脱离现实太远。 例如,想想返回负指标与载体使用天真的算法。 或嵌入到定制的硬件方案。 或者说,因为还是发生了 。
如果有这样的发展错误,你不应该有信心实现的任何恢复或错误处理机制。 这同样适用于硬件错误。