警告 C26441
ガード オブジェクトには名前を付ける必要があります (cp.44)
C++ Core Guidelines
CP.44:忘れずに自分の名前とunique_lock
名前をlock_guard
付けます
解説
標準ライブラリは、リソースの有効期間中にリソースへの同時アクセスを制御するのに役立つロックを提供します。 名前を指定せずにロック オブジェクトを宣言すると、コンパイラは、外側のスコープの末尾に存在するのではなく、直ちに破棄される一時オブジェクトを作成します。 したがって、ロック オブジェクトを変数に割り当てなくなると、(一時変数は一時的な変数であるため) ロック メカニズムが効果的に無効になります。 このルールは、このような意図しない動作の単純なケースをキャッチします。
この診断では、標準のロックの種類 std::scoped_lock
、 std::unique_lock
および std::lock_guard
. 警告 C26444 には、他の名前のない RAII 型が含まれています。
アナライザーは、コンストラクターの単純な呼び出しのみを分析します。 より複雑な初期化子式は、誤った警告の形式で不正確な結果を招く可能性があります。 アナライザーは、関数呼び出しに引数として渡されるか、関数呼び出しから返されたロックを無視します。 これらのロックがその関数呼び出しを意図的に保護しようとしているのか、または有効期間を 延長する必要があるかどうかを判断することはできません。 関数呼び出しによって返される型に対して同様の保護を提供するには、次のように注釈を付 [[nodiscard]]
けます。 コンストラクターに注釈を付 [[nodiscard]]
けて、その型の名前のないオブジェクトを回避することもできます。
struct X { [[nodiscard]] X(); };
void f() {
X{}; // warning C4834
}
アナライザーは、一時的として作成されたが、名前付き参照に割り当てられたロックを無視して有効期間を延長します。
コード分析名: NO_UNNAMED_GUARDS
例
この例では、スコープ付きロックの名前がありません。
void print_diagnostic(std::string_view text)
{
auto stream = get_diagnostic_stream();
if (stream)
{
std::lock_guard<std::mutex>{ diagnostic_mutex_ }; // C26441
write_line(stream, text);
}
}
エラーを修正するには、ロックに名前を付けて、有効期間を延長します。
void print_diagnostic(std::string_view text)
{
auto stream = get_diagnostic_stream();
if (stream)
{
std::lock_guard<std::mutex> lock{ diagnostic_mutex_ };
write_line(stream, text);
}
}