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


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

Избегайте goto (es.76)

Основные рекомендации по C++
ES.76: Избегайте goto

Использование goto широко считается опасной и подверженной ошибкам практике. Это допустимо только в созданном коде, например в синтаксическом анализаторе, созданном из грамматики. Благодаря современным функциям и служебным программам C++, предоставляемым библиотекой поддержки рекомендаций, это должно быть легко избежать goto в целом.

Замечания

  • Это правило предупреждает о любом вхождлении goto, даже если это происходит в недоставленном коде, за исключением кода шаблона, который никогда не использовался и поэтому игнорируется компилятором.
  • Предупреждения могут умножаться, если макрос содержит goto. Текущие механизмы отчетности указывают на все экземпляры, в которых развернут такой макрос. Его часто можно исправить в одном месте, изменив макрос или избегая его использования в пользу более обслуживаемых механизмов.

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

Пример

"Goto clean-up" в макросе

#define ENSURE(E, L) if (!(E)) goto L;

void poll(connection &c)
{
    ENSURE(c.open(), end);                  // C26438

    while (c.wait())
    {
        connection::header h{};
        connection::signature s{};
        ENSURE(c.read_header(h), end);      // C26438
        ENSURE(c.read_signature(s), end);   // C26438
        // ...
    }

end:
    c.close();
}

"Goto clean-up" в макросе, заменен на gsl::finally

void poll(connection &c)
{
    auto end = gsl::finally([&c] { c.close(); });

    if (!c.open())
        return;

    while (c.wait())
    {
        connection::header h{};
        connection::signature s{};
        if(!c.read_header(h))
            return;
       if(!c.read_signature(s))
            return;
        // ...
    }
}