I was looking at LazyInitializer.EnsureInitialized(ref T, Func{T}) in Reflector, and there appears to be a volatile local variable in that method volatile object local1 = s_barrier;
. I can think of two possible reasons for this:
-
.NET may get to use features that are not supported by a given language, or
-
The actual code does not declare a volatile local variable, but when the compiled code is decompiled by Reflector, it looks like a volatile local variable.
Does anyone know which is the case here (or whether there might be some other explanation)? If it is a matter of decompilation, does anyone have an idea of what the “true” code would look like?
This looks like a Reflector bug : it’s just a normal volatile read of the
s_barrierfield. There’s no “special” IL here that’s not expressible in C#.This is just the normal code the compiler emits when reading from a static volatile field.
Here’s a simpler repro: just compile the following (wrapped in a type) in release mode:
Reflector produces the following decompiled C#:
when the IL is actually:
UPDATE:
Here’s my guess about what’s happening: In release mode, the C# compiler optimizes away the assignment of the value of the field (the result of the volatile read) to the local variable (the
stlocinstruction) since the local is not subsequently used. This appears to confuse Reflector. If you changed the method to use the subsequently use local, thestloc(or similar) instruction would indeed be emitted, following which the decompiled output from Reflector looks sensible.