4

C++/CLI で、明示的な初期値なしでローカル参照変数を宣言すると、常に nullptr に初期化されると考えました。これは、ローカル ブロックへの 2 回目以降のエントリでは発生しないことがわかっています。これがサンプルコードです。

void main()
{
    for (int i=0; i<6; i++)
    {
        switch (i)
        {
        case 2:
            Console::WriteLine("i={0} localI and hashTable no longer in scope", i);
            break;
        default:
            {
                // Declare local reference variable
                Hashtable^ hashTable;
                Int32 localI;

                Console::WriteLine("i={0} localI={1}  {2}",
                    i, localI, 
                    hashTable == nullptr ? "hashTable=nullptr" : "hashTable NOT SET to nullptr"
                                   );
                hashTable = gcnew Hashtable();
                localI = i+1;
            }
            break;
        }
    }
}

これからの出力は次のとおりです。

i=0 localI=0  hashTable=nullptr
i=1 localI=1  hashTable NOT SET to nullptr
i=2 localI and hashTable no longer in scope
i=3 localI=2  hashTable NOT SET to nullptr
i=4 localI=4  hashTable NOT SET to nullptr
i=5 localI=5  hashTable NOT SET to nullptr

明示的な初期化を追加すると

Hashtable^ hashTable = nullptr;
Int32 localI = 99;

次に、各ループが参照と localI を再初期化します

i=0 localI=99  hashTable=nullptr
i=1 localI=99  hashTable=nullptr
i=2 localI and hashTable no longer in scope
i=3 localI=99  hashTable=nullptr
i=4 localI=99  hashTable=nullptr
i=5 localI=99  hashTable=nullptr

これは、私がMSDN で見つけ次の内容と矛盾しているようです。

「次のコード例は、ハンドルが宣言され、明示的に初期化されていない場合、デフォルトで nullptr に初期化されることを示しています。」

4

1 に答える 1

4

これは仕様によるもので、CLR はメソッド エントリでのみローカル変数を初期化します。メソッド内のスコープ ブロックは、コンパイル後に消える言語実装の詳細です。他のマネージ言語も同様で、VB.NET もまったく同じように動作します。C# も同様ですが、明確な代入規則があるため、この種のコードは許可されていません。

それ以外の場合、この動作により、ランタイムの実装が大幅に簡素化されます。ジッタは、エントリ時にスタックフレームをゼロに爆破するコードを生成するだけです。

于 2013-01-19T20:58:17.813 に答える