警告 C26447
関数は
noexcept
と宣言されているが、例外をスローする可能性がある関数 function_name を呼び出している (f.6)。
C++ Core Guidelines:
F.6: 関数でスローされない可能性がある場合は、noexcept として宣言する。
解説
このルールは、別のルール C26440 DECLARE_NOEXCEPT を修正します。これは、noexcept
としてマークする候補として最適な関数を検索します。 この場合、何らかの関数を noexcept
としてマークしたら、例外をスローする可能性がある他のコードを呼び出さずにコントラクトを保持する必要があるという考え方です。
- Microsoft C++ コンパイラは、関数本体内の
throw
ステートメントのような明らかな違反を既に処理しています (「C4297」を参照)。 - このルールでは、関数呼び出しのみを対象にしています。 例外をスローする可能性のある、
constexpr
ではないターゲットにフラグを設定します。 言い換えると、noexcept
、__declspec(nothrow)
、または throw() を使用することでスローされないと明示的にマークされません。 - コンパイラによって生成されるターゲット関数はスキップされ、例外仕様がコンパイラによって常に提供されるとは限らないため、ノイズを減らします。
- チェッカーは、
noexcept
として実装する必要がある特殊な種類のターゲット関数もスキップします。このルールは C26439 SPECIAL_NOEXCEPT によって適用されます。
例
#include <vector>
#include <string>
#include <istream>
std::vector<std::string> collect(std::istream& is) noexcept
{
std::vector<std::string> res;
for (std::string s; is >> s;) // C26447, `operator bool()` can throw, std::string's allocator can throw
res.push_back(s); // C26447, `push_back` can throw
return res;
}
関数シグネチャから noexcept
を削除することで、これらの警告を修正できます。