【问题标题】:Do I need to initobj/assign null to out arguments before ldloca and call?我是否需要在 ldloca 和调用之前将 initobj/assign 分配给 out 参数?
【发布时间】:2016-02-03 10:21:05
【问题描述】:

正如我所见,C# 编译器和Reflection.Emit 总是为值和引用类型变量发出.locals init(即使它们后来被无条件初始化)。所以它们可以作为输出参数传递:

    .maxstack 1
    .locals init (
        [0] object x)
    L_0000: ldloca.s x
    L_0002: call void Program::MethodWithOut(object&)
    L_0007: ret 

在没有init 的情况下使用.locals,所以在发出 call/callvirt 之前我需要确保变量已初始化?

【问题讨论】:

    标签: c# reflection.emit il


    【解决方案1】:

    简单的答案是init始终是使代码可验证所必需的。来自ECMA-335的§III.1.8.1.1 验证算法

    此外,可验证的方法应设置 localsinit 位 […]。如果未设置此位,则 CLI 可能会抛出 确认 在访问局部变量以及程序集的任何位置出现异常 包含该方法尚未被授予 SecurityPermission.SkipVerification.

    【讨论】:

      【解决方案2】:

      当您通过ref 传递参数时,您需要在传递之前对其进行初始化。 当您通过out 传递参数时,它们必须在被调用的方法内进行初始化。

      【讨论】:

      • 是的,我知道 C#。我问的是 IL 汇编规则。
      • 很抱歉让您感到困惑,请参阅更新后的问题。
      猜你喜欢
      • 2012-09-22
      • 1970-01-01
      • 1970-01-01
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      相关资源
      最近更新 更多