Warning C26438

Avoid goto (es.76)

C++ Core Guidelines:
ES.76: Avoid goto

The use of goto is widely considered a dangerous and error-prone practice. It's acceptable only in generated code, such as in a parser generated from a grammar. With modern C++ features and utilities provided by the Guidelines Support Library, it should be easy to avoid goto altogether.

Remarks

  • This rule warns on any occurrence of goto, even if it happens in dead code, except template code that's never used and so is ignored by the compiler.
  • Warnings can multiply when a macro contains goto. Current reporting mechanisms point to all instances where such a macro gets expanded. It can often be fixed in one place by changing the macro, or avoiding its use in favor of more maintainable mechanisms.

Code analysis name: NO_GOTO

Example

'goto clean-up' in macro

#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' in macro, replaced with 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;
        // ...
    }
}