Namespaces
Variants

goto statement

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
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
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
Special member functions
Templates
Miscellaneous

無条件に制御を転送します。

他の文を使用して制御を目的の場所に転送することが不可能な場合に使用されます。

目次

構文

attr  (オプション) goto label ;

説明

goto 文は、 label で指定された位置に制御を転送します。 goto 文は、参照する label と同じ関数内に存在する必要があり、labelの前または後に記述することができます。

制御の転送が自動変数のスコープを抜ける場合(例えば、そのような変数の宣言前の位置へ後方ジャンプする場合、または変数がスコープ内にある複合文から前方ジャンプする場合)、スコープを抜けたすべての変数のデストラクタが、構築順と逆の順序で呼び出されます。

goto 文は control-flow-limited statement 内への制御転送はできないが、control-flow-limited statement からの制御転送は可能です(スコープ内の自動変数に関する上記の規則が適用されます)。

制御の転送が自動変数のスコープ内に入る場合(例えば、宣言文を前方ジャンプによって飛び越えることにより)、プログラムは不適格(コンパイル不可)となります。ただし、スコープに入るすべての変数が以下の型を持つ場合は除きます:

  • 初期化子なしで宣言されたスカラ型
  • 自明なデフォルトコンストラクタと自明なデストラクタを持つクラス型で、初期化子なしで宣言されたもの
  • 上記のいずれかのcv修飾版
  • 上記のいずれかの配列

(注: 同じ規則がすべての制御転送形式に適用されます)

注記

Cプログラミング言語では、 goto 文にはより少ない制限があり、 variable-length array またはvariably-modified pointer以外の任意の変数のスコープに入ることができます。

キーワード

goto

#include <iostream>
struct Object
{
    // 非自明なデストラクタ
    ~Object() { std::cout << 'd'; }
};
struct Trivial
{
    double d1;
    double d2;
}; // 自明なコンストラクタとデストラクタ
int main()
{
    int a = 10;
    // gotoを使用したループ
label:
    Object obj;
    std::cout << a << ' ';
    a -= 2;
    if (a != 0)
        goto label;  // objのスコープ外にジャンプ、objのデストラクタを呼び出す
    std::cout << '\n';
    // gotoは多段階(ネストした)ループを効率的に抜けるために使用できる
    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; // nとtのスコープ内にジャンプ
    [[maybe_unused]] int n; // 初期化子なし
    [[maybe_unused]] Trivial t; // 自明なコンストラクタ/デストラクタ、初期化子なし
//  int x = 1;   // エラー: 初期化子あり
//  Object obj2; // エラー: 非自明なデストラクタ
label2:
    {
        Object obj3;
        goto label3; // 前方ジャンプ、obj3のスコープ外へ
    }
label3:
    std::cout << '\n';
}

出力:

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

関連項目

外部リンク

有名なエドガー・W・ダイクストラのエッセイ、 「Goto Considered Harmful」 (元々は「Communications of the ACM (CACM)への手紙」、第11巻第3号、1968年3月、147-148ページに掲載)は、このキーワードの不注意な使用が引き起こす数多くの微妙な問題についての考察を提示しています。