gcc(g++)では、C++関数への noexcept 指定子付け忘れを警告するオプションが提供される。Clangでは未実装。
要約:
- 評価結果が
false
となる noexcept 式オペランドのみが警告対象。残念ながら非常に限定的。 - 地味にペナルティを受ける「ムーブコンストラクタ/代入演算子への noexcept 指定忘れ」の検知にはあまり期待できない。*1
https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html
-Wnoexcept
(C++ and Objective-C++ only)
Warn when a noexcept-expression evaluates to false because of a call to a function that does not have a non-throwing exception specification (i.e.throw()
ornoexcept
) but is known by the compiler to never throw an exception.
下記コードではムーブコンストラクタ(X::X(X&&)
)への noexcept 指定忘れを検知できる。
struct X { X() {} X(const X&) = delete; // コピー禁止 X(X&&) /*noexcept*/ {} // ムーブのみ許可(noexcept無し) }; int main() { X x; std::cout << noexcept(X{std::move(x)}); } // 出力: 0
gcc 4.7.3のエラーメッセージ(明示的な -Wnoexcept オプション指定が必要):
In function 'int main()':
warning: noexcept-expression evaluates to 'false' because of a call to 'X::X(X&&)' [-Wnoexcept]
warning: but 'X::X(X&&)' does not throw; perhaps it should be declared 'noexcept' [-Wnoexcept]
関連URL
*1:例えば、標準 vector コンテナと noexcept 指定なしムーブ操作との関係が挙げられる。詳細はHow to enforce move semantics when a vector grows?やなぜstd::vector<>はnoexceptでないmove constructorを呼ばないのかを参照のこと。