C26438 NO_GOTO

"Avoid 'goto'."

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

Using of ‘goto’ is widely acknowledged as dangerous and error-prone practice. It is acceptable only in generated code (e.g. 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 which is never used and hence ignored by compiler.
    • Warnings can be noisy if they encounter a macro containing ‘goto’. Current reporting mechanism would point to all instances where such macro gets expanded. But the fix can usually be done in one place by changing the macro or avoiding use of it and leveraging more maintainable mechanisms.

Example

‘goto cleanup’ 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 cleanup’ 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;
        // ...
    }
}