goto-Anweisung
Ü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
[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. |