I notice that the following will compile and execute even though the local variables are not initialized. Is this a feature of Span?
void Uninitialized()
{
This looks like an issue caused by reference assemblies, required because of the way that Span
has framework-specific internals.
This means that in the reference assembly: there are no fields (edit: this isn't quite true - see footnote).
A struct
is considered assigned (for the purposes of "definite assignment") if all fields are assigned, and in this case the compiler is seeing "all zero of zero fields have been assigned: all good - this variable is assigned". But the compiler doesn't seem to know about the actual fields, so it is being misled into allowing something that is not technically valid.
You definitely shouldn't rely on this behaving nicely! Although in most cases .locals init
should mean you don't actually get anything too horrible. However, there is currently some work in progress to allow people to suppress .locals init
in some cases - I dread to think what could happen in that scenario here - especially since Span
works much like a ref T
- that could get very very dangerous if the field really isn't initialized to zero.
Interestingly, it might already be fixed: see this example on sharplab. Alternatively, maybe sharplab is using a concrete target framework, rather than reference assemblies.
Edit: very oddly, if I load the reference assembly into ildasm
or reflector, I can see:
.field private initonly object _dummy
which is the spoofed field in the reference assembly that is meant to stop this from happening, but... it looks like it isn't working very reliably right now!
Update: apparently the difference here is a subtle but known compiler issue that remains for compatibility reasons; definite assignment of structs considers private fields of types that are known locally, but does not consider private reference-type fields of types in external assemblies.