goto 文
From cppreference.com
無条件に制御を転送します。
他の文では制御を目的の場所に転送できない場合に使用します。
目次 |
[編集] 構文
attr (省略可能) goto ラベル ; |
|||||||||
[編集] 説明
goto 文は、ラベルで指定された場所に制御を転送します。goto 文は、参照するラベルと同じ関数内に存在する必要があり、ラベルの前に現れても後に現れても構いません。
制御の転送により、自動変数のスコープを抜ける場合(例えば、そのような変数の宣言より前の地点にジャンプしたり、変数がスコープ内にある複合文からジャンプしたりする場合)、スコープを抜けたすべての変数のデストラクタが、構築とは逆の順序で呼び出されます。
goto 文は、制御フロー制限文内へ制御を転送することはできませんが、制御フロー制限文から制御を転送することはできます(スコープ内の自動変数に関する上記の規則が適用されます)。
制御の転送によって自動変数のスコープに入る場合(例えば、宣言文を飛び越して前方へジャンプする場合)、スコープに入るすべての変数が以下の型である場合を除き、プログラムは不正な形式(コンパイルできない)となります
- 初期化子なしで宣言されたスカラー型
- 自明なデフォルトコンストラクタと自明なデストラクタを持ち、初期化子なしで宣言されたクラス型
- 上記のいずれかのcv修飾バージョン
- 上記のいずれかの配列
(注:同じ規則はすべての形式の制御転送に適用されます)
[編集] 備考
Cプログラミング言語では、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
[編集] 関連項目
| goto のC言語ドキュメント
|
[編集] 外部リンク
|
人気のあるエドガー・W・ダイクストラのエッセイ、「Goto Considered Harmful(gotoは有害である)」(原題は「Letter to Communications of the ACM (CACM)」, vol. 11 #3, March 1968, pp. 147-148。)は、このキーワードの不用意な使用が引き起こす多くの微妙な問題について概説しています。 |