goto
語句
來自 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
[編輯] 參閱
C 文件 關於 goto
|
[編輯] 外部連結
Edsger W. Dijkstra 的著名論文《Goto Considered Harmful》(最初發表於“Letter to Communications of the ACM (CACM)”, vol. 11 #3, 1968年3月, pp. 147-148.),對不謹慎使用此關鍵詞可能引入的許多微妙問題進行了調查。 |