名前空間
変種
操作

goto ステートメント

From cppreference.com
< c‎ | language

指定された場所に無条件で制御を転送します。

従来の構文では制御を転送できない場合に、目的の場所に制御を転送するために使用されます。

目次

[編集] 構文

attr-spec-seq(optional) goto label ;
label - goto ステートメントのターゲット ラベル
attr-spec-seq - (C23)goto ステートメントに適用される 属性のオプションリスト

[編集] 説明

goto ステートメントは、名前付き ラベル (goto ステートメントと同じ関数内に存在しなければなりません) が前に付いているステートメントへの無条件ジャンプ (制御の転送) を引き起こします。ただし、このジャンプが 可変長配列またはその他の 可変修飾型のスコープに入ってしまう場合は例外です。(since C99)

ラベルとは、コロン (:) の後に続く識別子です。(until C23) ラベルは「関数スコープ」を持つ唯一の識別子です。つまり、関数内で出現した場所ならどこからでも (goto ステートメントで使用) できます。1 つのステートメントの前に複数のラベルが存在しても構いません。

変更されていない変数のスコープに入ることは許可されます。

goto lab1; // OK: going into the scope of a regular variable
    int n = 5;
lab1:; // Note, n is uninitialized, as if declared by int n;
 
//   goto lab2;   // Error: going into the scope of two VM types
     double a[n]; // a VLA
     int (*p)[n]; // a VM pointer
lab2:

goto が VLA のスコープを離れる場合、それは解放されます (初期化が再度実行される場合は再割り当てされる可能性があります)。

{
   int n = 1;
label:;
   int a[n]; // re-allocated 10 times, each with a different size
   if (n++ < 10) goto label; // leaving the scope of a VM
}
(C99以降)

[編集] キーワード

goto

[編集] 注意

宣言はステートメントではないため、宣言の前のラベルにはヌルステートメント (コロンの直後のセミコロン) を使用する必要があります。ブロックの終端の前のラベルにも同様に適用されます。

(C23まで)

C++ では goto ステートメントに追加の制限が課せられますが、宣言の前のラベル (C++ ではステートメント) は許可されます。

[編集]

#include <stdio.h>
 
int main(void)
{
    // goto can be used to leave a multi-level loop easily
    for (int x = 0; x < 3; x++) {
        for (int y = 0; y < 3; y++) {
            printf("(%d;%d)\n",x,y);
            if (x + y >= 3) goto endloop;
        }
    }
endloop:;
}

出力

(0;0)
(0;1)
(0;2)
(1;0)
(1;1)
(1;2)

[編集] 参照

  • C17標準 (ISO/IEC 9899:2018)
  • 6.8.6.1 The goto statement (p: 110-111)
  • C11標準 (ISO/IEC 9899:2011)
  • 6.8.6.1 The goto statement (p: 152-153)
  • C99標準 (ISO/IEC 9899:1999)
  • 6.8.6.1 The goto statement (p: 137-138)
  • C89/C90標準 (ISO/IEC 9899:1990)
  • 3.6.6.1 The goto statement

[編集] 関連項目

C++ ドキュメント (goto ステートメント)
English 日本語 中文(简体) 中文(繁體)