From ECMA 335 I.12.4.1 Method calls
The local variable array always has null for object types and for fields within value types that hold objects. In addition, if
.locals init
is set, then the local variable array is initialized to 0 for integral types and 0.0 for floating point types. Value types are not initialized by CLI, but verified code will supply a call to an initializer as part of the method's entry point code.
So
Does "initialized to 0 for integral types and 0.0 for floating point types" mean "zeroes the value types"?
Does it mean: regardless of
.locals init
, CLI must always ensure that object types are set to null upon method entry? Then why does it differentiate object types and value types here: isn't zero out value types similar to zero out object type?How to understand that "value types are not initialized by CLI"?
What does this mean: "verified code will supply a call to an initializer as part of the method's entry point code"? Isn't verification part of CLI?
From ECMA 335 III.1.8.1.1 Verification algorithm
Verifiable methods shall have
.locals init
set. If not set, CLI might throw aVerificationException
where the assembly has not been grantedSecurityPermission.SkipVerification
. CLI might optionally choose to perform definite assignment analysis (to determine which location are written before read) to allows a CIL-to-native-code compiler to minimize its performance impact for this requirement.
If .locals init
is set, the spec requires that CLI must zero the local variable array upon method entry. This means the zeroing machine code needs to be execute upon entry. So, how would "definite assignment analysis" help, given that the possibly unnecessary zeroing is already done?
Apologies if I didn't make myself clear. I will try my best to improve my questions based on comments.
This just says that any memory established for storing integral types including Byte, Short, Int, Long, UInt, etc should have that memory cleared and the value set to 0, and Float, Double, etc should be 0.0. In .Net, this is the expected default value for the local variables for value types.
Ensuring that object references on the heap start off with an address pointing to null may require a different setup than forcing actual values in a memory address on the stack to have a zero value for the value types. So while objects are always null, value types are only zeroed out if the .locals init is set.
Value types do not have a constructor. The memory is allocated when you dimension the variable, but no default initialization call takes place for value types in CLI.
It sounds like verified code is a notch above the basic level provided directly by the CLI, and among other things requires value type initialization. But I'm just guessing on that one. Sort of like declaring it "unsafe" vs. "managed" or whatever.
It sounds like when zeroing values CLI makes a judgement call as it is zeroing values to decide if it actually needs to do so or not. But it sounds like this option is not always possible, depending on the native platform, or else depending on the memory size or something.