Namensräume
Varianten
Aktionen

goto-Anweisung

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
goto - return
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

Überträgt die Kontrolle bedingungslos.

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

Inhalt

[bearbeiten] Syntax

attr (optional) goto label ;

[bearbeiten] Erklärung

Die goto-Anweisung überträgt die Kontrolle an die durch label angegebene Stelle. Die goto-Anweisung muss sich in derselben Funktion wie das label befinden, auf das sie sich bezieht; sie kann vor oder nach dem Label erscheinen.

Wenn die Kontrolle den Geltungsbereich von automatischen Variablen verlässt (z. B. durch Zurückspringen zu einem Punkt vor der Deklaration solcher Variablen oder durch Vorwärtssprung aus einer zusammengesetzten Anweisung, in der die Variablen Geltungsbereich haben), werden die Destruktoren für alle Variablen aufgerufen, deren Geltungsbereich verlassen wurde, in umgekehrter Reihenfolge ihrer Konstruktion.

Die goto-Anweisung kann die Kontrolle nicht in eine kontrollflussbeschränkte Anweisung übertragen, kann aber die Kontrolle aus einer kontrollflussbeschränkten Anweisung heraus übertragen (die obigen Regeln bezüglich automatischer Variablen im Geltungsbereich werden befolgt).

Wenn die Kontrolle in den Geltungsbereich von automatischen 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 sind
  • Klassentypen mit trivialen Standardkonstruktoren und trivialen Destruktoren, die ohne Initialisierer deklariert sind
  • cv-qualifizierte Versionen einer der obigen
  • Arrays von einem der obigen

(Hinweis: dieselben Regeln gelten für alle Formen der Kontrollübertragung)

[bearbeiten] Hinweise

In der Programmiersprache C hat die goto-Anweisung weniger Einschränkungen und kann in den Geltungsbereich jeder Variablen eintreten, außer bei variablenlangen Arrays oder variabel modifizierten Zeigern.

[bearbeiten] Schlüsselwörter

goto

[bearbeiten] Beispiel

#include <iostream>
 
struct Object
{
    // non-trivial destructor
    ~Object() { std::cout << 'd'; }
};
 
struct Trivial
{
    double d1;
    double d2;
}; // trivial ctor and dtor
 
int main()
{
    int a = 10;
 
    // loop using goto
label:
    Object obj;
    std::cout << a << ' ';
    a -= 2;
 
    if (a != 0)
        goto label;  // jumps out of scope of obj, calls obj destructor
    std::cout << '\n';
 
    // goto can be used to efficiently leave a multi-level (nested) loops
    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; // jumps into the scope of n and t
 
    [[maybe_unused]] int n; // no initializer
 
    [[maybe_unused]] Trivial t; // trivial ctor/dtor, no initializer
 
//  int x = 1;   // error: has initializer
//  Object obj2; // error: non-trivial dtor
 
label2:
    {
        Object obj3;
        goto label3; // jumps forward, out of scope of 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

[bearbeiten] Siehe auch

C-Dokumentation für goto

[bearbeiten] Externe Links

Der populäre Essay von Edsger W. Dijkstra, „Goto Considered Harmful“ (ursprünglich in „Letter to Communications of the ACM (CACM)“, Bd. 11 Nr. 3, März 1968, S. 147-148.), bietet eine Übersicht über die vielen subtilen Probleme, die der unvorsichtige Gebrauch dieses Schlüsselworts einführen kann.