Skip to content

Latest commit

 

History

History
71 lines (54 loc) · 1.8 KB

c26438.md

File metadata and controls

71 lines (54 loc) · 1.8 KB
title C26438
ms.date 11/15/2017
ms.topic conceptual
f1_keywords
C26438
helpviewer_keywords
C26438
ms.assetid c7b3f59c-fb2f-4816-bda4-0fad23c80d83

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;
        // ...
    }
}