Advertencia C26448
Considere la posibilidad de usar
gsl::finally
si la acción final está pensada (gsl.util)
C++ Core Guidelines: GSL.util: Utilidades
La biblioteca Guidelines Support Library proporciona una práctica utilidad para implementar el concepto de acción final. Puesto que el lenguaje C++ no admite construcciones try-finally, se hizo común implementar tipos de limpieza personalizados que invocaran acciones arbitrarias en la destrucción. La utilidad gsl::finally
se implementa de esta manera y proporciona una manera más uniforme de realizar acciones finales en una base de código.
También hay casos en los que las acciones finales se realizan de forma antigua de C mediante goto
instrucciones (lo que no recomienda C26438 NO_GOTO). Es difícil detectar la intención exacta en el código que usa goto
en gran medida , pero algunas heurística pueden ayudar a encontrar mejores candidatos para la limpieza.
Comentarios
- Esta regla es ligera y usa nombres de etiqueta para adivinar las oportunidades de usar objetos de acción finales.
- Los nombres de etiqueta que pueden generar una advertencia contienen palabras como "end", "final", "clean", etc.
- Las advertencias aparecen en las instrucciones
goto
. Es posible que vea una salida detallada en algunas ocasiones, pero la salida puede ayudar a priorizar el código, en función de su complejidad. - Esta regla siempre va emparejada con C26438 NO_GOTO. En función de las prioridades, se puede deshabilitar una de estas reglas.
Nombre de análisis de código: USE_GSL_FINALLY
Ejemplo
Limpieza con varias instrucciones 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();
}
Limpieza con varias instrucciones goto reemplazadas 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;
// ...
}
}