Agr*_*hak 5 c++ optimization throw
根据优化C++,
对于您确定永远不会抛出异常的函数,使用空的异常规范(即,对声明追加throw()).
如果我知道90%的方法都不会抛出异常怎么办?将throw()附加到所有这些方法似乎是非常规和冗长的.如果没有,有什么好处?或者我在这里误解了什么?
C++ 11已经推出noexcept,throw有点弃用(根据这个效率较低)
noexcept是throw()的改进版本,在C++ 11中已弃用.与throw()不同,noexcept不会调用std :: unexpected并且可能会或可能不会展开堆栈,这可能允许编译器在没有throw()的运行时开销的情况下实现noexcept.
当违反空投掷规范时,您的程序将被终止; 这意味着你应该只将你的函数声明为非抛出,只有当它们具有无抛出异常保证时.
最后你需要一个非投掷的移动构造函数(指定noexcept)以便能够使用r值ref版本std::vector<T>::push_back(在这里查看更好的解释)
该标准throw()不会增强可扩展性.
如果某个方法被标记为,throw()那么编译器将被强制检查是否从该方法抛出异常并展开堆栈 - 就像该函数未标记为throw().唯一真正的区别在于,对于标记throw()的函数,当异常离开函数时,unexpected_handler将调用全局(通常调用terminate()),将堆栈展开到该级别,而不是没有异常规范的函数的行为,该异常规范将正常处理异常.
对于前C++ 11代码,Sutter和Alexandrescu在"C++编码标准"中提出:
避免异常规范.
除了这些规范之外:不要在函数上编写异常规范,除非你被迫(因为你无法更改的其他代码已经引入了它们;请参阅异常).
...
一个常见但不正确的信念是,异常规范静态地保证函数将仅抛出列出的异常(可能没有),并基于该知识启用编译器优化
事实上,异常规范实际上做了一些略微但根本不同的事情:它们导致编译器以函数体周围的隐式try/catch块的形式注入额外的运行时开销,以通过运行时检查来强制执行该函数只发出列出的异常(可能没有),除非编译器可以静态地证明永远不会违反异常规范,在这种情况下可以自由地优化检查.异常规范既可以启用也可以防止进一步的编译器优化(除了已经描述过的固有开销); 例如,某些编译器拒绝内联具有异常规范的函数.
请注意,在某些版本的Microsoft编译器中(我不确定此行为是否在更新版本中发生了变化,但我不这么认为),throw()将以非标准方式处理.throw()相当于__declspec(nothrow)允许编译器假定函数不会抛出异常,并且如果有的话,将导致未定义的行为.
C++ 11弃用了C++ 98样式异常规范并引入了noexcept关键字.Bjarne Stroustup的C++ 11常见问题解答说:
如果声明noexcept的函数抛出(以便异常试图转义,noexcept函数)程序终止(通过调用terminate()).对terminate()的调用不能依赖于处于明确定义状态的对象(即,不能保证已经调用了析构函数,没有保证堆栈展开,也没有恢复程序的可能性,好像没有遇到任何问题).这是故意的,并且使得noexcept成为一种简单,粗糙且非常有效的机制(比旧的动态throw()机制更有效).
在C++ 11中,如果从标记为函数的函数抛出异常,noexcept则编译器根本没有义务展开堆栈.这提供了一些优化可能性.Scott Meyers noexcept在他即将出版的"Effective Modern C++"一书中讨论了新内容.