在LazyInitializer.EnsureInitialized挥发性局部变量? [英] Volatile local variable in LazyInitializer.EnsureInitialized?

查看:231
本文介绍了在LazyInitializer.EnsureInitialized挥发性局部变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在看 LazyInitializer.EnsureInitialized(REF T,Func键横置)在反射器,而且似乎是在该方法挥发性局部变量 volatile对象LOCAL1 = s_barrier;
。我能想到的两个可能的原因:

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:


  1. .NET可能会使用不是由一个给定的语言支持的功能或

  1. .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?

推荐答案

这看起来像一个反射错误:这只是一个正常的波动的 s_barrier 字段读的。有没有特殊IL这里,这不是在C#中表达

This looks like a Reflector bug : it's just a normal volatile read of the s_barrier field. There's no "special" IL here that's not expressible in C#.

 L_000d: volatile. 
 L_000f: ldsfld object modreq(System.Runtime.CompilerServices.IsVolatile) System.Threading.LazyInitializer::s_barrier

这是只是正常的代码从静态挥发现场读取数据时,编译器会发出。

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:

private static volatile object field;

private static void Main()
{
    var temp = field;
}



反射产生以下反编译C#:

Reflector produces the following decompiled C#:

private static void Main()
{
    volatile object field = Program.field;
}



当IL居然是:

when the IL is actually:

L_0000: volatile. 
L_0002: ldsfld object modreq([mscorlib]System.Runtime.CompilerServices.IsVolatile) WindowsFormsApplication1.Program::field
L_0007: pop 
L_0008: ret 

更新
下面是我对发生的事情的猜测:在释放模式,C#编译器优化掉字段(挥发性读取的结果)来自本地的本地变量( stloc 指令)的值的分配是不是随后使用。这似乎混淆反射。如果你改变了方法来使用随后使用本地的, stloc (或类似)指令将确实发出,随后从反光反编译输出看上去很聪明。

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 stloc instruction) since the local is not subsequently used. This appears to confuse Reflector. If you changed the method to use the subsequently use local, the stloc (or similar) instruction would indeed be emitted, following which the decompiled output from Reflector looks sensible.

这篇关于在LazyInitializer.EnsureInitialized挥发性局部变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆