命名空间
变体
操作

goto 语句

来自 cppreference.com
< cpp‎ | 语言
 
 
C++ 语言
 
 

无条件地转移控制。

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

内容

[编辑] 语法

attr (可选) goto label ;

[编辑] 解释

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

如果控制转移退出任何自动变量的范围(例如,通过跳回变量声明之前的点,或跳出变量具有范围的复合语句),则将为所有退出范围的变量调用析构函数,其顺序与它们构造的顺序相反。

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

如果控制转移进入任何自动变量的作用域(例如,通过跳过声明语句),则程序格式不正确(无法编译),除非所有进入其作用域的变量具有以下类型

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

(注意:所有形式的控制转移都遵循相同的规则)

[编辑] 注释

在 C 编程语言中,The 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)”,第 11 卷第 3 期,1968 年 3 月,第 147-148 页),介绍了对使用此关键字可能引发的许多微妙问题的调查。