C++のswitch文で「crosses initialization of~」というエラーの対処

C++のswitch文で「crosses initialization of~」というエラーの対処

Posted at February 23,2017 12:03 AM
Tag:[C/C++]

C++のswitch文で「crosses initialization of」というエラーの対処方法について紹介します。

1.問題点

下記のサンプルプログラムを作りました。

sample.h

class Sample {
    public:
        Sample();
        void foo();
};

sample.cc

#include "stdio.h"
#include "sample.h"
 
Sample::Sample(){
}
 
void Sample::foo() {
    printf( "Hello World!\n" );
}

test.h

class Test {
    public:
        Test();
        void hoge(int);
};

test.cc

#include "test.h"
#include "sample.h"
 
Test::Test(){
}
 
void Test::hoge(int result) {
    switch (result) {
        case 0:
            break;
        case 1:
            Sample a;
            a.foo();
            break;
        default:
            break;
    }
}
 
int main () {
   Test test;
   test.hoge(1);
}

このプログラムをコンパイルすると、下記の「crosses initialization of」というエラーに遭遇します。

% g++ -g -w -ansi -fpermissive -I. test.cc sample.c
test.cc: メンバ関数 'void Test::hoge(int)' 内:
test.cc:13:20: エラー:   crosses initialization of 'Sample a'
             Sample a;
                    ^

2.原因

まず、switch文はcase内ではなく、switch全体でひとつのスコープとみなされます。

よって"case 1:"に実装された変数aのスコープはswitch文全体で有効になりますが、"case 1:"が実行されなかった場合、aの定義が行われないため、コンパイルエラーとなるようです。

今回はクラス定義が対象の処理でしたが、単なる変数定義でも同様のエラーが発生します。

3.対処

"case 1"全体をブロックで囲みます(括り方はさまざまですが少なくとも変数aがカッコで括ったブロック内にあること)。

void Test::hoge(int result) {
    switch (result) {
        case 0:
            break;
        case 1: {
            Sample a;
            a.foo();
            break;
        }
        default:
            break;
    }
}

これで変数のスコープがブロック内に閉じられます。

4.参考サイト

参考サイトは下記です。ありがとうございました。

関連記事
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)