警告 C26438

避免 goto (es.76)

C++ Core Guidelines:
ES.76:请避免使用 goto

使用 goto 被广泛认为是一种危险且容易出错的做法。 只接受在生成的代码中使用它,例如,在根据语法生成的分析器中。 借助 Guidelines 支持库提供的现代 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;
        // ...
    }
}