警告 C26448
最終的なアクションが意図されている場合は、
gsl::finally
の使用を検討してください (gsl.util)
「C++ Core Guidelines: GSL.util: Utilities (C++ Core Guidelines: GSL.util: ユーティリティ)」を参照してください
ガイドライン サポート ライブラリには、最終アクション の概念を実装するための便利なユーティリティがあります。 C++ 言語は try-finally コンストラクトをサポートしていないので、破棄時に任意のアクションを呼び出すカスタム クリーンアップ型を実装するのが一般的になりました。 gsl::finally
ユーティリティは、この方法で実装され、最終アクションをコード ベース全体でより統一された方法で実行できるようになっています。
また、 goto
ステートメントを使用して( C26438 NO_GOTOでは推奨されません)、C スタイルの古い方法で最終的なアクションが実行される場合もあります。 goto
を頻繁に使用するコードで正確な意図を検出するのは困難ですが、一部のヒューリスティックはクリーンアップの候補を見つけるのに役立ちます。
解説
- このルールは軽量であり、ラベル名を使用して、最終的なアクション オブジェクトを使用する機会を推測します。
- 警告が出る可能性があるラベル名には、"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;
// ...
}
}