命名空间
变体
操作

goto 语句

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
范围 for (C++11)
跳转语句
goto - return
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (在 C++17 前已弃用*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 

无条件地转移控制。

当无法使用其他语句将控制转移到所需位置时使用。

目录

[编辑] 语法

attr (可选) goto label ;

[编辑] 解释

goto 语句将控制转移到 label 指定的位置。goto 语句必须与它引用的 label 在同一个函数中,它可以出现在标签之前或之后。

如果控制转移退出了任何自动变量的作用域(例如,通过向后跳转到此类变量声明之前的点,或者通过向前跳转到变量作用域所在的复合语句之外),则会为所有作用域已退出的变量调用析构函数,顺序与它们的构造顺序相反。

goto 语句不能将控制转移到控制流受限语句中,但可以将控制从控制流受限语句中转移出来(遵循上述关于作用域内自动变量的规则)。

如果控制转移进入任何自动变量的作用域(例如,通过向前跳转到声明语句之上),则程序是非良构的(无法编译),除非所有进入作用域的变量都具有以下类型

  • 不带初始化器的标量类型
  • 具有平凡默认构造函数和平凡析构函数且不带初始化器声明的类类型
  • 上述类型之一的 cv 限定版本
  • 上述类型之一的数组

(注意:相同的规则适用于所有形式的控制转移)

[编辑] 注解

在 C 编程语言中,goto 语句的限制较少,可以进入除变长数组或可变修改指针之外的任何变量的作用域。

[编辑] 关键字

goto

[编辑] 示例

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

输出

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

[编辑] 参见

C 文档 关于 goto

[编辑] 外部链接

广受欢迎的 Edsger W. Dijkstra 论文,“Goto Considered Harmful” (最初发表于 "Letter to Communications of the ACM (CACM)", vol. 11 #3, March 1968, pp. 147-148.),概述了粗心使用此关键字可能引入的许多细微问题。