静态分析noexcept“违规行为”。在C ++中 [英] Static analysis of noexcept "violations" in C++

查看:125
本文介绍了静态分析noexcept“违规行为”。在C ++中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写例外安全代码。我发现使用C ++ 11的noexcept说明符使该目标更容易实现。

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.

当然,一般的想法是,函数应标记为'只有在它调用的所有函数也都标记为'noexcept'时,才可以使用noexcept。

The general idea, of course, is that a function should be marked as 'noexcept' if, and only if all the functions that it calls are also marked as 'noexcept'.

问题是在大型代码库中,来自不同补丁的补丁人们经常合并在一起,很难确保保持这种一致性。

The problem is that in a large code base, where patches from different people are often merged together, it is hard to ensure that this consistency is maintained.

因此,我希望能够进行静态分析,列出所有地点标记为 nothrow的函数会调用未标记为 nothrow的函数。

So I would like to be able to run a static analysis that could list all places where a function that is marked 'nothrow' calls a function that is not marked as 'nothrow'.

据我在手册页中看到的,GCC无法帮助我在这里。是否有任何独立工具可以帮助我?也许还有其他一些编译器?

As far as I can see in the man-page, GCC cannot help me here. Are there any stand-alone tools that can help me? Or maybe some other compilers?

推荐答案

如果您避免使用函数来指向函数指针(并认为它们不安全),这似乎是有可能的。该程序的ABT。 Clang的AST(尽管其名称)就是这样的ABT:您将看到函数的声明和定义。通过一次完成一个定义的工作,您已经有了一个良好的基线。

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.

另一方面,我想知道这是否是实用的。问题是,执行内存分配的任何函数都被(自愿)标记为可能抛出(因为 new 从不返回null,而是抛出 bad_alloc )。因此,在大多数情况下,您的 noexcept 仅限于少数功能。

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.

当然,动态条件,例如@GManNickG,例如:

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();
}

即使 T :: bar noexcept ,取消引用 optional< T> 可能会抛出(如果什么也没有)。当然,这忽略了我们已经排除了这一事实(在这里)。

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).

在没有明确的条件何时函数 throw 静态分析可能证明...无用。语言习语在设计时要考虑到例外情况。

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

注意:作为题外话,可选类可能是进行了重写,以免暴露出反引用,因此 noexcept (如果有回调):

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.

这篇关于静态分析noexcept“违规行为”。在C ++中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆