Поделиться через


Предупреждение C26448

Рассмотрите возможность использования gsl::finally , если окончательное действие предназначено (gsl.util)

Основные рекомендации по C++: GSL.util: служебные программы

Библиотека поддержки рекомендаций предоставляет удобную программу для реализации окончательной концепции действия . Так как язык C++ не поддерживает конструкции try-finally , он стал общим для реализации пользовательских типов очистки, которые вызывают произвольные действия по уничтожению. Эта gsl::finally программа реализуется таким образом и обеспечивает более универсальный способ выполнения конечных действий в базе кода.

Существуют также случаи, когда окончательные действия выполняются в старомодном стиле C с помощью goto инструкций (которые не рекомендуется использовать C26438 NO_GOTO). Трудно обнаружить точное намерение в коде, который в значительной степени использует goto, но некоторые эвристики могут помочь найти лучших кандидатов на очистку.

Замечания

  • Это правило упрощено и использует имена меток, чтобы угадать возможности использования конечных объектов действия.
  • Имена меток, которые могут вызывать предупреждение, содержат такие слова, как end, final, clean и т. д.
  • Предупреждения отображаются в goto инструкциях. Подробные выходные данные могут отображаться в некоторых случаях, но выходные данные могут помочь в приоритете кода в зависимости от сложности.
  • Это правило всегда входит в пару с NO_GOTO C26438. В зависимости от приоритетов один из этих правил можно отключить.

Имя анализа кода: USE_GSL_FINALLY

Пример

Очистка с несколькими операторами 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();
}

Очистка с несколькими операторами goto заменена на 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;
        // ...
    }
}