用C noexcept“违规”的静态分析+(Static analysis of noexcept

2019-07-19 03:49发布

我试着写异常安全的代码。 我发现,使用C ++ 11的noexcept符使得这一目标一大堆更容易实现。

总的想法,当然,是一个功能应该被标记为如果“noexcept”,且仅当它调用的函数也被标记为“noexcept”。

问题是,在一个大的代码库,其中来自不同的人的补丁常常合并在一起,很难保证这种一致性得以保持。

所以我想能够运行一个静态分析,可以列出其中被标记“无抛出”一个函数调用没有被标记为“无抛出”功能的所有地方。

至于我可以在手册页看到,GCC不能帮助我在这里。 是否有任何独立的工具,可以帮助我吗? 或者一些其他的编译器?

Answer 1:

如果你避免指针功能(和认为他们是不安全的),通过使用该程序的ABT一定是的可能。 铛的AST是(尽管它的名字)这样的ABT:你会看到双方的声明和功能定义。 通过在一个时间做你的工作一个定义,你已经有了一个良好的基线。

在另一方面,我不知道这是否是可行的 。 你看,问题是,执行内存分配任何功能(自动)标记为可能抛出(因为new永远不会返回null,但抛出bad_alloc替代)。 因此,您的noexcept将被限制的功能,在大多数情况下屈指可数。

当然还有所有的动态条件像@GManNickG暴露出来,例如:

void foo(boost::optional<T> const t&) {
    if (not t) { return; }

    t->bar();
}

即使T::barnoexcept ,访问一个optional<T>可能抛出(如果有什么)。 当然,这忽略了我们已经排除了这一可能性(在这里)的事实。

而对时功能可能清 throwstatic分析可能证明......没用。 语言成语设计时考虑的例外。


注:作为一个题外话,可选类可以改写以免暴露解引用,并因此被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.


文章来源: Static analysis of noexcept “violations” in C++