2

特定のオブジェクトの値を交換しなければならない場合に遭遇しました。私自身のずさんなコピーアンドペーストのために、タイプ宣言も誤ってコピーしました。簡単な例を次に示します。

int main()
{
    int i = 42;
    cout << "i = " << i++ << endl;

    // ... much later

    if( isSwapRequired == true )
    {
        int i = 24;
        cout << "i = " << i++ << endl;
    }
    cout << "i = " << i++ << endl;
}

残念なことに、コンパイラーはこれをキャッチせず、さらにi = 24独自の小さなスコープで動作させました。その後、スコープ外で、iとして残ることがわかり43ます。i両方が同じレベルにある場合、コンパイラーはこの間違いを強制的にキャッチすることに気づきました。コンパイラが複数の宣言を異なる方法で処理する理由はありますか?

重要な場合は、VS10を使用しています。

4

2 に答える 2

8

このプログラムは、標準で定められた規則に従って完全に有効で正しいものです。コンパイラは何もキャッチする必要はなく、キャッチするものは何もありません。

この標準では、同じ名前の変数がそれぞれのスコープに存在することが許可されており、特定のスコープでそれらを使用するときに参照される変数に関するルールが明確に定義されています。同じ名前の変数は、グローバルスコープで変数を非表示またはシャドウします。

ローカルスコープ内(条件付きifブロック内)で、ローカルに宣言されiたものはグローバルを非表示にしiます。iこのスコープ内でグローバルにアクセスする必要がある場合は、を使用する必要があります::i

条件付きブロックの外側にi存在するのは、グローバルに宣言されただけですi


コメントの質問への回答:

コンパイラは実際にこれを警告する必要はありませんが、最高の警告レベルを有効にしてプログラムをコンパイルするか、この特定の動作を警告するようにコンパイラに明示的に指示すると、ほとんどのコンパイラがこの診断を提供します。

GCCの場合、を使用できます-Wshadow

-Wshadow

ローカル変数または型宣言が別の変数、パラメーター、型、またはクラスメンバー(C ++の場合)をシャドウするとき、または組み込み関数がシャドウされるときはいつでも警告します。C ++では、ローカル変数が明示的なtypedefをシャドウする場合は警告しますが、struct / class/enumをシャドウする場合は警告しません。

于 2013-03-27T13:11:40.753 に答える
1

iのそれぞれが異なるスコープを持ち、ローカルスコープが常にグローバルスコープを優先する ため、これは複数の宣言ではありません。

iトップレベルのmain()使用から使用したい場合::i

チュートリアルについては、こちらをご覧ください。

于 2013-03-27T13:12:00.910 に答える