Aviso C26441
Os objetos de guarda devem ser nomeados (cp.44)
Diretrizes Principais do C++
CP.44: Lembre-se de nomear seu lock_guard
s e unique_lock
s
Comentários
A biblioteca padrão fornece bloqueios para ajudar a controlar o acesso simultâneo a recursos durante sua vida útil. Quando você declara um objeto de bloqueio sem um nome, o compilador cria um objeto temporário que é imediatamente destruído em vez de um que vive até o final do escopo de delimitação. Portanto, a falha em atribuir um objeto de bloqueio a uma variável é um erro que efetivamente desabilita o mecanismo de bloqueio (porque as variáveis temporárias são transitórias). Essa regra detecta casos simples de tal comportamento não intencional.
Esse diagnóstico analisa apenas os tipos std::scoped_lock
de bloqueio padrão , std::unique_lock
e std::lock_guard
. O aviso C26444 abrange outros tipos de RAII sem nome.
O analisador analisa apenas chamadas simples para construtores. Expressões de inicializador mais complexas podem levar a resultados imprecisos na forma de avisos perdidos. O analisador ignora bloqueios passados como argumentos para chamadas de função ou retornados de chamadas de função. Ele não consegue determinar se esses bloqueios estão deliberadamente tentando proteger essa chamada de função ou se sua vida útil deve ser estendida. Para fornecer proteção semelhante para tipos retornados por uma chamada de função, anote-os com [[nodiscard]]
. Você também pode anotar construtores com [[nodiscard]]
para evitar objetos sem nome desse tipo:
struct X { [[nodiscard]] X(); };
void f() {
X{}; // warning C4834
}
O analisador ignora bloqueios criados como temporários, mas atribuídos a referências nomeadas para estender sua vida útil.
Nome da análise de código: NO_UNNAMED_GUARDS
Exemplo
Neste exemplo, o nome do bloqueio com escopo está ausente.
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);
}
}
Para corrigir o erro, dê um nome ao bloqueio, que estende sua vida útil.
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);
}
}