C++のswitch文でオブジェクトを生成しようとするとエラーになる
きっと知っている人にとっては当たり前なんでしょうが、ハマッたので備忘録として。
サンプルコード(コンパイルエラー版)
#include <iostream> using namespace std; struct Hoge { int i; }; Hoge get_hoge(int i) { switch(i) { case 1: // { Hoge hoge = {1}; return hoge; // } default: // { Hoge hoge = {2}; return hoge; // } } } int main(int argc, char **argv) { Hoge hoge1 = get_hoge(1); cout << hoge1.i << endl; Hoge hoge2 = get_hoge(2); cout << hoge2.i << endl; return 0; }
以下はMaxOS Xでビルドした時のメッセージ(Eclipse、C++プラグイン使用)。
エラーは二つの原因によって発生している。
1つめは、caseとdefault部分で変数名が重複していため。
2つめは、オブジェクトの生成が出来ずにエラーになるため。
実行結果
make all Building file: ../main.cpp Invoking: GCC C++ Compiler g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o" "../main.cpp" ../main.cpp: In function 'Hoge get_hoge(int)': ../main.cpp:23: error: jump to case label ../main.cpp:20: error: crosses initialization of 'Hoge hoge' ../main.cpp:25: error: redeclaration of 'Hoge hoge' ../main.cpp:20: error: 'Hoge hoge' previously declared here make: *** [main.o] Error 1
サンプルコード(コンパイル成功版)
#include <iostream> using namespace std; struct Hoge { int i; }; Hoge get_hoge(int i) { switch(i) { case 1: { Hoge hoge = {1}; return hoge; } default: { Hoge hoge = {2}; return hoge; } } } int main(int argc, char **argv) { Hoge hoge1 = get_hoge(1); cout << hoge1.i << endl; Hoge hoge2 = get_hoge(2); cout << hoge2.i << endl; return 0; }
実行結果
1 2
正常な方は、ブレースをつけてスコープを明確にしたため、うまく動くのでしょう。