9

このコード フラグメントが正常に動作する理由

void foo(int i)
{
    switch(i) {
    case 1:
    {
        X x1;
        break;
    }
    case 2:
        X x2;
        break;
    }
}

次はコンパイルエラーになります(「x1」の初期化は「ケース」ラベルによってスキップされます)?

void foo(int i)
{
    switch(i) {
    case 1:
        X x1;
        break;
    case 2:
        X x2;
        break;
    }
}

ブレースを使用すると新しいスコープが導入されることを理解しています。したがって、ストレージは x1 の左ブレースに到達するまで割り当てられません。ただし、x2 は中かっこで囲まずにケース ラベル内で初期化されます。これもエラーではないでしょうか?

x2 の初期化は、両方のコード フラグメントで条件付きでスキップできると思います

4

5 に答える 5

7

1: 有効

 case 1:
        {
        X x1;
        break;
        }

条件に一致しない場合、x1 それ以上のステートメントで使用できないため、これで実行時エラーが発生することはありません。x1中括弧の外に存在しようとしません。


2: 無効

 switch(i) {
    case 1:
        X x1; //don't break
        i = 2;
        ...
        ...
        ...
     case 2:
        x1.someOperation()

 }

上記では、最初に iだった場合、オブジェクトを構築する前にヒットします。2x1.someOperation()X x1

コンパイルが許可された場合、 case:1が 2 の前に実行されたかどうか (およびオブジェクトが構築されたかどうか) に応じて、実行時エラーがスローされるかどうかが決まります。したがって、コンパイラによって許可されていません。


ユーザー定義のコンストラクターを持つことができないPlain Old Data 型でも同じことが可能です。

于 2012-11-16T11:38:16.983 に答える
4

Xが非 POD の場合にのみエラーが発生することに注意してください。が POD の場合X、エラーは発生しません (中かっこを使用しない場合)。

非 POD の場合、同じスコープで宣言されている変数の初期化をスキップすることはできません。中かっこを使用しないとコンパイル エラーが発生します。これは、でそのような変数の初期化をスキップswitchできるため、同時に、その下のすべてのラベルで使用できるようになるためです。それは危険です。case

この行に沿って考えてみてください:iがの場合、コントロールは初期化せずに直接22 番目にジャンプし、初期化されていなくても 2 番目のケースで使用できるようになります。それは意味がありません。したがって、言語ではエラーである必要があります。casex1x1


ちなみに、POD と非 POD については、次のトピックを参照してください。

于 2012-11-16T11:38:40.680 に答える
2

一般的な考え方は、それぞれcaseが孤立したスコープではないということです:同じスコープ (つまり、ブロック全体) で以前に宣言されているため、下のコードcase 2は変数を参照できます: もちろん、それは初期化されていません。エラーになります。x1switch

中括弧を追加すると、実際にはそれぞれcaseのスコープが分割されcase 1、外部で参照できない変数を宣言できるようになります。

于 2012-11-16T11:49:19.543 に答える
0

条件ステートメント内で変数を作成することはお勧めできません。ステートメントの外側で変数を作成switchし、条件 on に従ってそれに値を割り当てることをお勧めしますi

void foo(int i) {

    X x1;

    switch(i) {
        case 1:
            x1 = ...;
            break;
        case 2:
            x1 = ...;
            break;
    }
}
于 2012-11-16T11:37:35.427 に答える
0

失敗したバージョンでは、 の宣言は、ラベルx1の数行後までスコープ外になりません。case 2:それが問題です。宣言とそのスコープの終わりの間にラベルがx2ないため、の宣言は問題ありません。case

于 2012-11-16T16:51:54.703 に答える