警告 C26441
临界对象必须具有名称 (cp.44)
C++ Core Guidelines
CP.44:记住命名 lock_guard
和 unique_lock
注解
标准库提供了锁来帮助控制资源在其生命周期内的并发访问。 当声明一个没有名称的锁对象时,编译器会创建一个立即被破坏的临时对象,而不是一个一直存在到封闭范围末尾的对象。 因此,未能将锁对象分配给变量是一个错误,它会有效地禁用锁定机制(因为临时变量是瞬态的)。 此规则会捕获此类意外行为的简单情况。
此诊断仅分析标准锁类型 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);
}
}