Edit

Share via


Warning C26441

Guard objects must be named (cp.44)

C++ Core Guidelines

CP.44: Remember to name your lock_guards and unique_locks

Remarks

The standard library provides locks to help control concurrent access to resources during their lifetime. When you declare a lock object without a name, the compiler creates a temporary object that's immediately destructed rather than one that lives to the end of the enclosing scope. So, failure to assign a lock object to a variable is a mistake that effectively disables the locking mechanism (because temporary variables are transient). This rule catches simple cases of such unintended behavior.

This diagnostic only analyzes the standard lock types std::scoped_lock, std::unique_lock, and std::lock_guard. Warning C26444 covers other unnamed RAII types.

The analyzer only analyzes simple calls to constructors. More complex initializer expressions may lead to inaccurate results in the form of missed warnings. The analyzer ignores locks passed as arguments to function calls or returned from function calls. It's unable to determine if those locks are deliberately trying to protect that function call or if their lifetime should be extended. To provide similar protection for types returned by a function call, annotate them with [[nodiscard]]. You can also annotate constructors with [[nodiscard]] to avoid unnamed objects of that type:

struct X { [[nodiscard]] X(); };

void f() {
    X{}; // warning C4834
}

The analyzer ignores locks created as temporaries but assigned to named references to extend their lifetime.

Code analysis name: NO_UNNAMED_GUARDS

Example

In this example, the name of the scoped lock is missing.

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);
    }
}

To fix the error, give a name to the lock, which extends its lifetime.

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);
    }
}

See also

C26444