Aviso C26448
Considere usar
gsl::finally
se a ação final for pretendida (gsl.util)
Diretrizes Principais do C++: GSL.util: Utilitários
A Biblioteca de Suporte de Diretrizes fornece um utilitário conveniente para implementar o conceito de ação final. Como a linguagem C++ não dá suporte a constructos try-finally, tornou-se comum implementar tipos de limpeza personalizados que invocam ações arbitrárias sobre destruição. O utilitário gsl::finally
é implementado dessa forma e fornece uma maneira mais uniforme de executar ações finais em uma base de código.
Há também casos em que as ações finais são executadas de maneira antiquada no estilo C usando goto
instruções (o que é desencorajado pelo C26438 NO_GOTO). É difícil detectar a intenção exata no código que usa goto
muito, mas algumas heurísticas podem ajudar a encontrar melhores candidatos para limpeza.
Comentários
- Essa regra é leve e usa nomes de rótulo para adivinhar oportunidades de usar objetos de ação finais.
- Nomes de rótulo que podem gerar um aviso contêm palavras como "end", "final", "clean" e assim por diante.
- Os avisos aparecem nas instruções
goto
. Você pode ver uma saída detalhada em algumas ocasiões, mas a saída pode ajudar na priorização do código, dependendo de sua complexidade. - Essa regra sempre entra em par com C26438 NO_GOTO. Dependendo das prioridades, uma dessas regras pode ser desativada.
Nome da análise de código: USE_GSL_FINALLY
Exemplo
Limpeza com várias instruções 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();
}
Limpeza com várias instruções goto substituídas por 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;
// ...
}
}