Ссылка C++/CLI не инициализируется в nullptr при последующих записях в локальном блоке

Я думал, что в C++/CLI объявление локальной ссылочной переменной без явного начального значения всегда инициализирует ее как nullptr. Я обнаружил, что это не происходит на втором и последующих записях в локальном блоке. Вот пример кода.

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;

Затем каждый цикл повторно инициализирует ссылку и локальный

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".

1 ответ

Решение

Это разработано, CLR только инициализирует локальные переменные на входе метода. Блоки области действия внутри метода - это детали реализации языка, которые исчезают после компиляции. Другие управляемые языки похожи, VB.NET ведет себя точно так же. C# тоже, но не допускает такого рода код из-за своего определенного правила присваивания.

Это поведение значительно упрощает реализацию во время выполнения. Джиттер просто генерирует код, чтобы взорвать стековый фрейм до нуля при входе.

Другие вопросы по тегам