警告 C26448
最終的なアクションが意図されている場合の使用
gsl::finally
を検討する (gsl.util)
「C++ Core Guidelines: GSL.util: Utilities (C++ Core Guidelines: GSL.util: ユーティリティ)」を参照してください
ガイドライン サポート ライブラリには、最終アクション の概念を実装するための便利なユーティリティがあります。 C++ 言語は try-finally コンストラクトをサポートしていないので、破棄時に任意のアクションを呼び出すカスタム クリーンアップ型を実装するのが一般的になりました。 gsl::finally
ユーティリティは、この方法で実装され、最終アクションをコード ベース全体でより統一された方法で実行できるようになっています。
ステートメント (C26438 NO_GOTOでは推奨されません) を使用goto
して、以前の C スタイルの方法で最終的なアクションが実行される場合もあります。 頻繁に使用goto
するコードで正確な意図を検出するのは難しいですが、一部のヒューリスティックは、クリーンup のより良い候補を見つけるのに役立ちます。
解説
- このルールは軽量であり、ラベル名を使用して、最終的なアクション オブジェクトを使用する機会を推測します。
- 警告が出る可能性があるラベル名には、"end"、"final"、"clean" などのワードが含まれます。
- 警告は
goto
ステートメントに示されます。 場合によっては詳細な出力が表示されることがありますが、複雑さに応じてコードの優先順位付けに役立つ場合があります。 - この規則は、必ず C26438 NO_GOTO とペアになります。 優先順位に応じて、これらの規則のいずれかを無効にすることができます。
コード分析名: USE_GSL_FINALLY
例
複数の goto ステートメントを使用したクリーンアップ:
void poll(connection_info info)
{
connection c = {};
if (!c.open(info))
return;
while (c.wait())
{
connection::header h{};
connection::signature s{};
if (!c.read_header(h))
goto end; // C26448 and C26438
if (!c.read_signature(s))
goto end; // C26448 and C26438
// ...
}
end:
c.close();
}
複数の goto ステートメントでクリーンアップを次のように gsl::finally
置き換えます。
void poll(connection_info info)
{
connection c = {};
if (!c.open(info))
return;
auto end = gsl::finally([&c] { c.close(); });
while (c.wait())
{
connection::header h{};
connection::signature s{};
if (!c.read_header(h))
return;
if (!c.read_signature(s))
return;
// ...
}
}