Namespaces
Variants

goto statement

From cppreference.net

制御を無条件に所望の位置へ転送します。

従来の構文では目的の場所に制御を転送することが不可能な場合に使用されます。

目次

構文

attr-spec-seq (オプション) goto label ;
label - goto 文の対象 label
attr-spec-seq - (C23) オプションの attributes リスト、 goto 文に適用される

説明

goto 文は、指定された ラベル (goto文と同じ関数内に存在しなければならない)で始まる文への無条件ジャンプ(制御の転送)を引き起こします。 ただし、このジャンプが 可変長配列 または他の 可変修飾型 のスコープに入る場合は除きます。 (C99以降)

ラベルは、識別子の後にコロン( : )が続くもの および文 (C23まで) です。ラベルは 関数スコープ を持つ唯一の識別子です:同じ関数内の任意の場所(goto文内で)使用できます。任意の文の前に複数のラベルが存在する場合があります。

非可変長修飾変数のスコープへの進入は許可される:

goto lab1; // OK: 通常変数のスコープへの進入
    int n = 5;
lab1:; // 注意:nは初期化されていない(int n; で宣言されたかのように)
//   goto lab2;   // エラー:2つのVM型のスコープへの進入
     double a[n]; // VLA
     int (*p)[n]; // VMポインタ
lab2:

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

{
   int n = 1;
label:;
   int a[n]; // 10回再割り当てされ、それぞれ異なるサイズを持つ
   if (n++ < 10) goto label; // VMのスコープからの離脱
}
(C99以降)

キーワード

goto

注記

宣言は文ではないため、宣言の前のラベルは空文(コロンの直後のセミコロン)を使用しなければなりません。ブロックの終了前のラベルにも同じことが適用されます。

(until 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 goto文 (p: 110-111)
  • C11規格 (ISO/IEC 9899:2011):
  • 6.8.6.1 goto文 (p: 152-153)
  • C99規格 (ISO/IEC 9899:1999):
  • 6.8.6.1 goto文 (p: 137-138)
  • C89/C90標準 (ISO/IEC 9899:1990):
  • 3.6.6.1 goto文

関連項目

C++ ドキュメント for goto statement