Namespaces
Variants

goto statement

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
goto - return
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Überträgt die Steuerung bedingungslos.

Wird verwendet, wenn es anderweitig unmöglich ist, die Kontrolle an die gewünschte Stelle mit anderen Anweisungen zu übertragen.

Inhaltsverzeichnis

Syntax

attr  (optional) goto label ;

Erklärung

Die goto -Anweisung überträgt die Steuerung an die durch die Marke angegebene Position. Die goto -Anweisung muss sich in derselben Funktion wie die Marke befinden, auf die sie verweist; sie kann vor oder nach der Marke erscheinen.

Wenn die Übertragung der Kontrolle den Gültigkeitsbereich automatischer Variablen verlässt (z.B. durch Rücksprung zu einem Punkt vor den Deklarationen solcher Variablen oder durch Vorwärtssprung aus einem zusammengesetzten Anweisungsblock, in dem die Variablen gültig sind), werden die Destruktoren für alle Variablen aufgerufen, deren Gültigkeitsbereich verlassen wurde, in der umgekehrten Reihenfolge ihrer Konstruktion.

Die goto -Anweisung kann die Steuerung nicht in eine kontrollflussbeschränkte Anweisung übertragen, kann jedoch die Steuerung aus einer kontrollflussbeschränkten Anweisung heraus übertragen (die oben genannten Regeln bezüglich automatischer Variablen im Gültigkeitsbereich werden befolgt).

Wenn die Übertragung der Kontrolle in den Geltungsbereich automatischer Variablen eintritt (z.B. durch Vorwärtssprung über eine Deklarationsanweisung), ist das Programm fehlerhaft (kann nicht kompiliert werden), es sei denn, alle Variablen, deren Geltungsbereich betreten wird, haben folgende Typen:

  • Skalare Typen, die ohne Initialisierer deklariert werden
  • Klassentypen mit trivialen Standardkonstruktoren und trivialen Destruktoren, die ohne Initialisierer deklariert werden
  • CV-qualifizierte Versionen eines der oben genannten
  • Arrays eines der oben genannten

(Hinweis: Dieselben Regeln gelten für alle Formen der Steuerungsübertragung)

Hinweise

In der Programmiersprache C hat die goto -Anweisung weniger Einschränkungen und kann in den Gültigkeitsbereich jeder Variablen außer variable-length array oder variably-modified pointer eintreten.

Schlüsselwörter

goto

Beispiel

#include <iostream>
struct Object
{
    // nicht-trivialer Destruktor
    ~Object() { std::cout << 'd'; }
};
struct Trivial
{
    double d1;
    double d2;
}; // trivialer ctor und dtor
int main()
{
    int a = 10;
    // Schleife mit goto
label:
    Object obj;
    std::cout << a << ' ';
    a -= 2;
    if (a != 0)
        goto label;  // springt aus dem Gültigkeitsbereich von obj, ruft obj Destruktor auf
    std::cout << '\n';
    // goto kann verwendet werden, um mehrstufige (verschachtelte) Schleifen effizient zu verlassen
    for (int x = 0; x < 3; ++x)
        for (int y = 0; y < 3; ++y)
        {
            std::cout << '(' << x << ',' << y << ") " << '\n';
            if (x + y >= 3)
                goto endloop;
        }
endloop:
    std::cout << '\n';
    goto label2; // springt in den Gültigkeitsbereich von n und t
    [[maybe_unused]] int n; // kein Initialisierer
    [[maybe_unused]] Trivial t; // trivialer ctor/dtor, kein Initialisierer
//  int x = 1;   // Fehler: hat Initialisierer
//  Object obj2; // Fehler: nicht-trivialer dtor
label2:
    {
        Object obj3;
        goto label3; // springt vorwärts, aus dem Gültigkeitsbereich von obj3
    }
label3:
    std::cout << '\n';
}

Ausgabe:

10 d8 d6 d4 d2
(0,0)
(0,1)
(0,2)
(1,0)
(1,1)
(1,2)
d
d

Siehe auch

Externe Links

Der bekannte Essay von Edsger W. Dijkstra, „Goto Considered Harmful“ (ursprünglich in "Letter to Communications of the ACM (CACM)", Bd. 11 #3, März 1968, S. 147-148.), stellt eine Übersicht über die vielen subtilen Probleme dar, die der unbedachte Einsatz dieses Schlüsselworts verursachen kann.