在 ldloca 和调用之前,我是否需要 initobj/assign null 来输出参数?
Do I need to initobj/assign null to out arguments before ldloca and call?
正如我所见,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 之前我需要确保变量已初始化?
当您通过 ref
传递参数时,您需要在传递之前对它们进行初始化。
当您通过 out
传递参数时,它们必须在被调用的方法中进行初始化。
简单的答案是 init
总是 使代码可验证所必需的。来自ECMA-335的§III.1.8.1.1验证算法:
Furthermore, verifiable methods shall have the localsinit bit set […]. If this bit is not set, then a CLI might throw a
Verification
exception at any point where a local variable is accessed, and where the assembly
containing that method has not been granted
SecurityPermission.SkipVerification
.
正如我所见,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 之前我需要确保变量已初始化?
当您通过 ref
传递参数时,您需要在传递之前对它们进行初始化。
当您通过 out
传递参数时,它们必须在被调用的方法中进行初始化。
简单的答案是 init
总是 使代码可验证所必需的。来自ECMA-335的§III.1.8.1.1验证算法:
Furthermore, verifiable methods shall have the localsinit bit set […]. If this bit is not set, then a CLI might throw a Verification exception at any point where a local variable is accessed, and where the assembly containing that method has not been granted
SecurityPermission.SkipVerification
.