C++/CLI 引用未在后续进入本地块时初始化为 nullptr
Posted
技术标签:
【中文标题】C++/CLI 引用未在后续进入本地块时初始化为 nullptr【英文标题】:C++/CLI reference not initialized to nullptr on subsequent entries into local block 【发布时间】:2013-01-03 07:11:40 【问题描述】:我认为在 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 上找到的 here 的内容相矛盾:
“下面的代码示例表明,当句柄被声明但未显式初始化时,它们默认初始化为 nullptr。”
【问题讨论】:
【参考方案1】:这是设计使然,CLR 仅在方法入口时初始化局部变量。方法中的作用域块是编译后消失的语言实现细节。其他托管语言类似,VB.NET 的行为方式完全相同。 C# 也可以,但由于其明确的分配规则,不允许这种代码。
否则,此行为会大大简化运行时实现。抖动只是生成代码以在入口处将堆栈帧爆破为零。
【讨论】:
谢谢,这是有道理的。因此,MSDN 参考会更准确地说 “所有默认初始化仅在方法开始时发生一次,而不是在本地范围块内。” 我被 C++/CLI 宣传默认初始化而没有提及例外。让使用未初始化变量的规则与 C# 匹配会更加稳健。除了更多的调试实践之外,我不确定在 C++/CLI 中允许使用未初始化的句柄会给我带来什么。谢谢@Hans,感谢您的广博知识。以上是关于C++/CLI 引用未在后续进入本地块时初始化为 nullptr的主要内容,如果未能解决你的问题,请参考以下文章
调试包含在 C++/CLI DLL 中的静态库时,调试器不会进入本机代码
DevOps使用教程 华为云(14)git如何将本地项目初始化为远程仓库