C++
編譯錯誤會發生在第 11 行,g++ 噴出的錯誤訊息是
11:9: error: jump to case label
11 | default:
| ^~~~~~~
9:17: note: crosses initialization of 'int i'
9 | int i = 0;
這表示的是 i 在 case label 0 的 scope 裡面有被宣告並同時初始化(declaration with initialization),根據 C++ standard 6.7.3,
declaration statement 在 declaration with initialization 的區域變數是無法自動帶進其他 block ( switch 其實就是多個 {label, block} + goto 組成)。
讓它在 C++ compiler 編譯過的其中一個方法是,根據標準,不使用 declaration with initialization,而是把宣告與定義分開,即:
但是這樣子在 C code 是依然是無法編譯過的,因為在 C 跟 C++ 中的編譯錯誤的原因不同,接下來看看 C 的情況。11:9: error: jump to case label
11 | default:
| ^~~~~~~
9:17: note: crosses initialization of 'int i'
9 | int i = 0;
這表示的是 i 在 case label 0 的 scope 裡面有被宣告並同時初始化(declaration with initialization),根據 C++ standard 6.7.3,
declaration statement 在 declaration with initialization 的區域變數是無法自動帶進其他 block ( switch 其實就是多個 {label, block} + goto 組成)。
讓它在 C++ compiler 編譯過的其中一個方法是,根據標準,不使用 declaration with initialization,而是把宣告與定義分開,即:
C
:9:13: error: a label can only be part of a statement and a declaration is not a statement
9 | int i = 0;
| ^~~
Compiler returned: 1
根據 C standard 6.8.1,declaration 並不是 statement,只有 statement 可以被 labeled,所以會編譯錯誤,注意 C 並不禁止在 block 裡使用宣告過但未初始化的變數。
一個修正方法是,在 label 後加上 empty statement,即
不過這樣在 C++ 依然不會編譯過。
然而在 C 與 C++ 同時可以編譯過的實作中,如
可編譯過的原因也是不同的:
- C: {...} 為 compound statement (即 block),故可以被 labeled
- C++: 透過 block 將 local 變數的 scope 限制在 labeled block 裡。
參考資料:
沒有留言:
張貼留言