Compartir vía


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 gotoen 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 del 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;
        // ...
    }
}