Static analysis of noexcept “violations” in C++

后端 未结 1 1118
醉梦人生
醉梦人生 2020-12-30 04:26

I\'m trying to write exception safe code. I find that using C++11\'s noexcept specifier makes this goal a whole lot more achievable.

The general idea, of course, is

相关标签:
1条回答
  • 2020-12-30 04:59

    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.
    
    0 讨论(0)
提交回复
热议问题