我试着写异常安全的代码。 我发现,使用C ++ 11的noexcept符使得这一目标一大堆更容易实现。
总的想法,当然,是一个功能应该被标记为如果“noexcept”,且仅当它调用的函数也被标记为“noexcept”。
问题是,在一个大的代码库,其中来自不同的人的补丁常常合并在一起,很难保证这种一致性得以保持。
所以我想能够运行一个静态分析,可以列出其中被标记“无抛出”一个函数调用没有被标记为“无抛出”功能的所有地方。
至于我可以在手册页看到,GCC不能帮助我在这里。 是否有任何独立的工具,可以帮助我吗? 或者一些其他的编译器?
如果你避免指针功能(和认为他们是不安全的),通过使用该程序的ABT一定是的可能。 铛的AST是(尽管它的名字)这样的ABT:你会看到双方的声明和功能定义。 通过在一个时间做你的工作一个定义,你已经有了一个良好的基线。
在另一方面,我不知道这是否是可行的 。 你看,问题是,执行内存分配任何功能(自动)标记为可能抛出(因为new
永远不会返回null,但抛出bad_alloc
替代)。 因此,您的noexcept
将被限制的功能,在大多数情况下屈指可数。
当然还有所有的动态条件像@GManNickG暴露出来,例如:
void foo(boost::optional<T> const t&) {
if (not t) { return; }
t->bar();
}
即使T::bar
是noexcept
,访问一个optional<T>
可能抛出(如果有什么)。 当然,这忽略了我们已经排除了这一可能性(在这里)的事实。
而对时功能可能清况 throw
, static
分析可能证明......没用。 语言成语设计时考虑的例外。
注:作为一个题外话,可选类可以改写以免暴露解引用,并因此被noexcept
(如果回调是):
template <typename T>
class maybe {
public:
template <typename OnNone, typename OnJust>
void act(OnNone&& n, OnJust&& j) noexcept(noexcept(n()) and
noexcept(j(std::declval<T&>())))
{
if (not _assigned) { n(); return; }
j(*reinterpret_cast<T*>(&_storage));
}
private:
std::aligned_storage<sizeof(T), alignof(T)>::type _storage;
bool _assigned;
};
// No idea if this way of expressing the noexcept dependency is actually correct.