C++中“违反”的静态分析

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

当然,一般的想法是,当且仅当函数调用的所有函数也标记为“noexcept”时,函数才应标记为“noexcept”

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

因此,我希望能够运行一个静态分析,列出标记为“nothrow”的函数调用未标记为“nothrow”的函数的所有位置

就我在手册页中所见,GCC在这方面帮不了我。有没有可以帮助我的独立工具?或者其他编译器

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

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

当然,还有所有的动态条件,比如@gmannickgexposed,例如:

void foo(boost::可选<T>const T&){
如果(不是t){return;}
t->杆();
}

即使T::barnoexcept,也要取消对可选项的引用<T&gt可能会抛出(如果没有)。当然,这忽略了一个事实,即我们已经排除了这一点(此处)

如果没有明确的条件打开,函数可能会抛出静态分析可能会证明。。。无用的语言习语的设计是有例外的


注意:作为题外话,可选类可以重写,以避免公开解引用,因此是noexcept(如果回调是):

模板<typename T>
也许是上课吧{
公众:
模板<typename OnNone,typename OnJust>
无效行为(OnNone&n,OnJust&j)noexcept(noexcept(n())和
无例外(j(std::declval<T>()))
{
如果(未指定){n();返回;}
j(*重新解释铸造<T*>(&U存储));
}
私人:
标准::对齐存储<大小f(T),对齐f(T)>::类型存储;
指定的布尔;
};
//不知道这种表达noexcept依赖关系的方式是否正确。

发表评论