assert
是一个纯C宏,没有考虑到C++机制。另一方面,C++定义了
std::logic_error
,用于在程序逻辑出错的情况下抛出异常(因此命名为“逻辑错误”)。手动抛出实例可能是完美的、更符合C++风格的assert
替代方法。问题在于,
assert
和abort
都会立即终止程序而不调用析构函数,从而跳过清理工作,而手动抛出异常会增加不必要的运行时成本。解决这个问题的一种方法是创建一个自己的断言宏SAFE_ASSERT
,它与C的对应物类似,但在失败时抛出异常。我能想到三种解决这个问题的方法:
- 坚持使用C的assert。由于程序立即终止,正确卸载更改并不重要。此外,在C++中使用#define与使用C中的情况一样糟糕。 - 抛出异常并在main()中捕获异常。允许代码在程序的任何状态下跳过析构函数是不良实践,必须尽一切可能避免,调用terminate()也是如此。如果抛出异常,则必须捕获它们。 - 抛出异常并让其终止程序。一个异常终止程序是可以接受的,并且由于NDEBUG,这在发布版本中永远不会发生。捕获异常是不必要的,并将内部代码的实现细节暴露给main()。
这个问题有明确的答案吗?有任何专业参考资料吗?
编辑:跳过析构函数当然不是未定义行为。
static_assert
,请确保在适当的地方使用它。 - Flexostd::bug
吗? - R. Martinho Fernandesstd::abort()
时不需要担心未定义行为,它只会引发一个信号,导致进程终止。 - Kerrek SB