Static analysis of noexcept “violations” in C++

一曲冷凌霜 提交于 2019-11-30 06:43:17

It certainly seems possible if you avoid pointer to functions (and deem them unsafe) by using the ABT of the program. Clang's AST is (despite its name) such an ABT: you will see both declarations and definitions of the functions. By doing your work one definition at a time, you will already have a good baseline.

On the other hand, I wonder whether this is practical. See, the problem is that any function performing a memory allocation is (voluntarily) marked as potentially throwing (because new never returns null, but throws bad_alloc instead). Therefore, your noexcept will be limited to a handful of functions in most cases.

And of course there are all the dynamic conditions like @GManNickG exposed, for example:

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

    t->bar();
}

Even if T::bar is noexcept, dereferencing an optional<T> may throw (if there is nothing). Of course, this ignores the fact that we already ruled this out (here).

Without having clear conditions on when a function might throw, static analysis might prove... useless. The language idioms are designed with exceptions in mind.


Note: as a digression, the optional class could be rewritten so as not to exposed dereferencing, and thus be noexcept (if the callbacks are):

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.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!