4

我认为在 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;

然后每个循环重新初始化引用和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 回答