Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/goto"

From cppreference.com
< cpp‎ | language
m (See Also C documentation for goto)
m (Consistency with cpp/language/alignas)
 
(10 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{title|goto statement}}
+
{{title|{{tt|goto}} statement}}
 
{{cpp/language/statements/navbar}}
 
{{cpp/language/statements/navbar}}
  
Line 7: Line 7:
  
 
===Syntax===
 
===Syntax===
 
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc | {{spar|attr}}{{mark optional}} {{ttb|goto}} {{spar|label}} {{ttb|;}} }}
+
{{sdsc|{{spar optional|attr}} {{ttb|goto}} {{spar|label}} {{ttb|;}}}}
 
{{sdsc end}}
 
{{sdsc end}}
  
 
===Explanation===
 
===Explanation===
 
+
The {{c/core|goto}} statement transfers control to the location specified by {{rlp|statements#Labels|label}}. The {{c/core|goto}} statement must be in the same function as the {{spar|label}} it is referring, it may appear before or after the label.
The goto statement transfers control to the location specified by {{spar|label}}. The goto statement must be in the same function as the {{spar|label}} it is referring, it may appear before or after the label.
+
  
 
If transfer of control exits the scope of any automatic variables (e.g. by jumping backwards to a point before the declarations of such variables or by jumping forward out of a compound statement where the variables are scoped), the destructors are called for all variables whose scope was exited, in the order opposite to the order of their construction.
 
If transfer of control exits the scope of any automatic variables (e.g. by jumping backwards to a point before the declarations of such variables or by jumping forward out of a compound statement where the variables are scoped), the destructors are called for all variables whose scope was exited, in the order opposite to the order of their construction.
  
The {{tt|goto}} statement cannot transfer control into a {{rlp|try_catch|try-block}} or into a catch-clause, but can transfer control out of a try-block or a catch-clause (the rules above regarding automatic variables in scope are followed)
+
The {{c/core|goto}} statement cannot transfer control into a {{rlp|statements#Control-flow-limited statements|control-flow-limited statement}}, but can transfer control out of a control-flow-limited statement (the rules above regarding automatic variables in scope are followed).
  
If transfer of control enters the scope of any automatic variables (e.g. by jumping forward over a declaration statement), the program is ill-formed (cannot be compiled), unless all variables whose scope is entered have
+
If transfer of control enters the scope of any automatic variables (e.g. by jumping forward over a declaration statement), the program is ill-formed (cannot be compiled), unless all variables whose scope is entered have the following types:
@1@ scalar types declared without initializers
+
* scalar types declared without initializers
@2@ class types with trivial default constructors and trivial destructors declared without initializers
+
* class types with trivial default constructors and trivial destructors declared without initializers
@3@ cv-qualified versions of one of the above
+
* cv-qualified versions of one of the above
@4@ arrays of one of the above
+
* arrays of one of the above
  
 
(Note: the same rules apply to all forms of transfer of control)
 
(Note: the same rules apply to all forms of transfer of control)
  
===Keywords===
+
===Notes===
 +
In the C programming language, the {{c/core|goto}} statement has fewer restrictions and can enter the scope of any variable other than [[c/language/array#Variable-length arrays|variable-length array]] or variably-modified pointer.
  
 +
===Keywords===
 
{{ltt|cpp/keyword/goto}}
 
{{ltt|cpp/keyword/goto}}
  
 
===Example===
 
===Example===
 
{{example
 
{{example
| code=
+
|code=
 
#include <iostream>
 
#include <iostream>
  
struct Object {
+
struct Object
 +
{
 
     // non-trivial destructor
 
     // non-trivial destructor
     ~Object() { std::cout << "d"; }
+
     ~Object() { std::cout << 'd'; }
 
};
 
};
  
struct Trivial {
+
struct Trivial
 +
{
 
     double d1;
 
     double d1;
 
     double d2;
 
     double d2;
Line 54: Line 56:
 
label:
 
label:
 
     Object obj;
 
     Object obj;
     std::cout << a << " ";
+
     std::cout << a << ' ';
     a = a - 2;
+
     a -= 2;
 
+
   
     if (a != 0) {
+
     if (a != 0)
 
         goto label;  // jumps out of scope of obj, calls obj destructor
 
         goto label;  // jumps out of scope of obj, calls obj destructor
    }
 
 
     std::cout << '\n';
 
     std::cout << '\n';
 
+
   
     // goto can be used to leave a multi-level loop easily
+
     // goto can be used to efficiently leave a multi-level (nested) loops
     for (int x = 0; x < 3; x++) {
+
     for (int x = 0; x < 3; ++x)
         for (int y = 0; y < 3; y++) {
+
         for (int y = 0; y < 3; ++y)
             std::cout << "(" << x << ";" << y << ") " << '\n';
+
        {
             if (x + y >= 3) {
+
             std::cout << '(' << x << ',' << y << ") " << '\n';
 +
             if (x + y >= 3)
 
                 goto endloop;
 
                 goto endloop;
            }
 
 
         }
 
         }
     }
+
      
 
endloop:
 
endloop:
 
     std::cout << '\n';
 
     std::cout << '\n';
 
+
   
 
     goto label2; // jumps into the scope of n and t
 
     goto label2; // jumps into the scope of n and t
     int n; // no initializer
+
      
     Trivial t; // trivial ctor/dtor, no initializer
+
    [[maybe_unused]] int n; // no initializer
//  int x = 1; // error: has initializer
+
      
 +
    [[maybe_unused]] Trivial t; // trivial ctor/dtor, no initializer
 +
   
 +
//  int x = 1;   // error: has initializer
 
//  Object obj2; // error: non-trivial dtor
 
//  Object obj2; // error: non-trivial dtor
 +
   
 
label2:
 
label2:
 
 
     {
 
     {
 
         Object obj3;
 
         Object obj3;
 
         goto label3; // jumps forward, out of scope of obj3
 
         goto label3; // jumps forward, out of scope of obj3
 
     }
 
     }
label3: ;
+
   
 
+
label3:
 +
    std::cout << '\n';
 
}
 
}
| output=
+
|output=
 
10 d8 d6 d4 d2
 
10 d8 d6 d4 d2
(0;0)  
+
(0,0)
(0;1)  
+
(0,1)
(0;2)  
+
(0,2)
(1;0)  
+
(1,0)
(1;1)  
+
(1,1)
(1;2)  
+
(1,2)
  
dd
+
d
 +
d
 
}}
 
}}
  
===See Also===
+
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc see c | c/language/goto}}
+
{{dsc see c|c/language/goto}}
 
{{dsc end}}
 
{{dsc end}}
  
[[de:cpp/language/goto]]
+
===External links===
[[es:cpp/language/goto]]
+
{{eli|
[[fr:cpp/language/goto]]
+
The popular Edsger W. Dijkstra essay, [http://david.tribble.com/text/goto.html “Goto Considered Harmful”] (originally, in "Letter to Communications of the ACM (CACM)", vol. 11 #3, March 1968, pp. 147-148.), presents a survey of the many subtle problems the careless use of this keyword can introduce.
[[it:cpp/language/goto]]
+
}}
[[ja:cpp/language/goto]]
+
 
[[pt:cpp/language/goto]]
+
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
[[ru:cpp/language/goto]]
+
[[zh:cpp/language/goto]]
+

Latest revision as of 11:20, 11 August 2024

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
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
const/volatile
decltype (C++11)
auto (C++11)
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
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Transfers control unconditionally.

Used when it is otherwise impossible to transfer control to the desired location using other statements.

Contents

[edit] Syntax

attr (optional) goto label ;

[edit] Explanation

The goto statement transfers control to the location specified by label. The goto statement must be in the same function as the label it is referring, it may appear before or after the label.

If transfer of control exits the scope of any automatic variables (e.g. by jumping backwards to a point before the declarations of such variables or by jumping forward out of a compound statement where the variables are scoped), the destructors are called for all variables whose scope was exited, in the order opposite to the order of their construction.

The goto statement cannot transfer control into a control-flow-limited statement, but can transfer control out of a control-flow-limited statement (the rules above regarding automatic variables in scope are followed).

If transfer of control enters the scope of any automatic variables (e.g. by jumping forward over a declaration statement), the program is ill-formed (cannot be compiled), unless all variables whose scope is entered have the following types:

  • scalar types declared without initializers
  • class types with trivial default constructors and trivial destructors declared without initializers
  • cv-qualified versions of one of the above
  • arrays of one of the above

(Note: the same rules apply to all forms of transfer of control)

[edit] Notes

In the C programming language, the goto statement has fewer restrictions and can enter the scope of any variable other than variable-length array or variably-modified pointer.

[edit] Keywords

goto

[edit] Example

#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';
}

Output:

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

[edit] See also

[edit] External links

The popular Edsger W. Dijkstra essay, “Goto Considered Harmful” (originally, in "Letter to Communications of the ACM (CACM)", vol. 11 #3, March 1968, pp. 147-148.), presents a survey of the many subtle problems the careless use of this keyword can introduce.