在C++11中,无条件的noexcept就是为了不会发射异常的函数准备的,考察C++98和C++11在表达函数不会发射异常时的差异:
int f(int x) throw(); // f不会发射异常,C++98风格 int f(int x) noexcept(); // f不会发射异常,C++11风格
如果,在运行期,一个异常逸出f的作用域,则f的异常规格被违反。在C++98异常规格下,调用栈会开解至f的调用方,然后执行一些与本条框不相关的动作后,程序终止。而在C++11异常规格下,运行期行为会稍有不同:程序执行终止之前,栈只是可能会被解开。
开解和可能开解调用栈,这一点点区别对于代码生成造成的影响之大可能出乎人们的意料。在带有noexcept声明函数中,优化器不需要在异常传出函数的前提下,将执行期栈保持在可开解状态;也不需要在异常溢出函数的前提下,保证所有其中的对象以其被构造顺序的逆序完成析构。而那些以throw()异常规格声明的函数就享受不到这样的优化灵活性;
ReType function(params) noexcept; // 最优化 ReType function(params) throw(); // 优化不够 ReType function(params) noexcept; // 优化不够
// 中间段看的比较模糊
考虑编译器一般对于识别函数实现及其异常规格的一致性不予支持的问题。
void setup(); //函数在别处定义
void cleanup();
void doWokr() noexcept {
setup(); // 建立要做的工作
//... // 完成要做的工作
cleanup(); // 执行清理动作
}
这里doWork带有noexcept声明的函数setup和cleanup。看起来自相矛盾,但是也有可能setup和cleanup已经在文档中写明它们不会发射异常。
由于有着确实的理由使得带有noexcept声明的函数依赖于缺乏noexcept保证的代码,C++允许此类代码通过编译,并且编译器通常不会就此生成警告
noexcept声明是函数接口的组成部分,这意味调用方可能会它有依赖
相对于不带noexcept声明的函数,带有noexcept声明的函数有更过机会得到优化
noexcept性质对于移动操作,swap,析构函数最有价值
大多数函数都是异常中立的,不具备noexcept性质



