Предупреждение 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;
// ...
}
}