EMCPP条款14:只要函数不会发射异常,就为其加上 noexcept 声明

YiQi 管理员

考虑一个函数 f,欲向调用方保证它们不会接收到异常。两种表达方式如下:

1
2
int f(int x) throw(); // no exceptions from f: C++98 style
int f(int x) noexcept; // no exceptions from f: C++11 style

如果,在运行期,一个异常逸出 f 的作用域,则 f 的异常规格袚违反。在 C++98 异常规格下,调用栈会开解至 f 的调用方,然后执行了一些与本条款无关的动作以后,程序执行中止。而在 C++11 异常规格下,运行期行为会稍有不同:程序执行中止之前,栈只是可能会开解。

开解调用栈,和可能开解调用栈,这一点点区别对于代码生成造成的影响之大可能出乎人们的意料。在带有 noexcept 声明的函数中,优化器不需要在异常传出函数的前提下,将执行期栈保持在可开解状态;也不需要在异常溢出函数的前提下,保证所有其中的对象以其被构造顺序的逆序完成析构。而那些以 throw() 异常规格声明的函数就享受不到这样的优化灵活性,和没有加异常规格声明的函数一样。这些可以总结为下述情况:

1
2
3
RetType function(params) noexcept; // most optimizable
RetType function(params) throw(); // less optimizable
RetType function(params); // less optimizable

仅仅这个就已经构成充分理由,让你给任何已知不会产生异常的函数加上 noexcept 声明了。

这个条款目前不太理解,等以后补全相关知识后会再更新

要点速记

  • noexcept 声明是函数接口的组成部分,这意味着调用方可能会对它有依赖 。
  • 相对于不带 noexcept 声明的函数,带有 noexcept 声明的函数有更多机会得到优化 。
  • noexcept 性质对于移动操作、 swap、函数释放函数和析构函数最有价值。
  • 大多数函数都是异常中立的,不具各 noexcept 性质。
此页目录
EMCPP条款14:只要函数不会发射异常,就为其加上 noexcept 声明