1

来自 ECMA 335 I.12.4.1 方法调用

对于对象类型和保存对象的值类型中的字段,局部变量数组始终为 null。此外,如果 .locals init设置了,则局部变量数组对于整型初始化为 0,对于浮点型初始化为 0.0。CLI 不会初始化值类型,但经过验证的代码将提供对初始化程序的调用,作为方法入口点代码的一部分。

所以

  1. “对于整数类型初始化为 0,对于浮点类型初始化为 0.0”是否意味着“将值类型归零”?

  2. 这是否意味着:不管怎样.locals init,CLI 必须始终确保在方法输入时将对象类型设置为 null?那为什么这里要区分对象类型和值类型:清零值类型不是类似于清零对象类型吗?

  3. 如何理解“CLI 未初始化值类型”?

  4. 这是什么意思:“经过验证的代码将提供对初始化程序的调用,作为方法入口点代码的一部分”?验证不是 CLI 的一部分吗?

来自 ECMA 335 III.1.8.1.1 验证算法

应有可验证的方法.locals init。如果未设置,CLI 可能会抛出VerificationException未授予程序集的位置 SecurityPermission.SkipVerification。CLI 可以选择执行明确的分配分析(以确定在读取之前写入的位置),以允许 CIL 到本机代码的编译器将其对此要求的性能影响降至最低。

如果.locals init设置,规范要求 CLI 在方法入口时必须将局部变量数组归零。这意味着需要在进入时执行归零机器代码。那么,鉴于可能不必要的归零已经完成,“明确的分配分析”将如何提供帮助?

抱歉,如果我没有说清楚。我会尽力根据评论改进我的问题。

4

1 回答 1

0
  1. 这只是说为存储整数类型(包括 Byte、Short、Int、Long、UInt 等)而建立的任何内存都应该清除该内存并将值设置为 0,而 Float、Double 等应该为 0.0。在 .Net 中,这是值类型的局部变量的预期默认值。

  2. 确保堆上的对象引用从指向 null 的地址开始可能需要不同的设置,而不是强制堆栈上的内存地址中的实际值具有值类型的零值。因此,虽然对象始终为空,但只有在设置了 .locals init 时,值类型才会被清零。

  3. 值类型没有构造函数。为变量设置维度时会分配内存,但在 CLI 中不会对值类型进行默认初始化调用。

  4. 听起来经过验证的代码比 CLI 直接提供的基本级别高出一个档次,除此之外还需要值类型初始化。但我只是猜测那个。有点像宣布它“不安全”与“托管”或其他什么。

  5. 这听起来像是当归零值 CLI 进行判断调用时,因为它正在归零值以决定它是否真的需要这样做。但听起来这个选项并不总是可行的,这取决于本机平台,或者取决于内存大小或其他东西。

于 2013-07-15T03:54:49.400 回答