我倾向于在我的 C++ 代码中添加大量断言,以便在不影响发布版本的性能的情况下更轻松地进行调试。现在,assert
是一个没有考虑 C++ 机制的纯 C 宏。
另一方面,C++ 定义了std::logic_error
,这意味着在程序逻辑出现错误的情况下抛出(因此得名)。抛出一个实例可能只是assert
.
问题是assert
两者abort
都立即终止程序而不调用析构函数,因此跳过清理,而手动抛出异常会增加不必要的运行时成本。解决这个问题的一种方法是创建一个自己的断言宏SAFE_ASSERT
,它的工作方式与 C 对应的一样,但在失败时抛出异常。
关于这个问题,我能想到三个观点:
- 坚持 C 的断言。由于程序会立即终止,因此更改是否正确展开并不重要。此外,
#define
在 C++ 中使用 s 也同样糟糕。 - 抛出异常并在 main() 中捕获它。允许代码在程序的任何状态下跳过析构函数是不好的做法,必须不惜一切代价避免,对 terminate() 的调用也是如此。如果抛出异常,则必须捕获它们。
- 抛出异常并让它终止程序。 终止程序的异常是可以的,并且由于
NDEBUG
,这将永远不会在发布版本中发生。捕获是不必要的,它会将内部代码的实现细节暴露给main()
.
这个问题有确定的答案吗?有什么专业的参考吗?
编辑:当然,跳过析构函数没有未定义的行为。