Chr*_*tle 6 c# il visual-studio-2013
我们在其中一个项目中的类中有以下方法:
private unsafe void SomeMethod()
{
// Beginning of the method omitted for brevity
var nv = new Vector4[x];
fixed (Vector4* vp = nv)
{
fixed (float* tp = /* Source float ptr */)
{
fixed (double* ap = /* Source double ptr */)
{
for (var i = atlArray.Length - 1; i >= 0; --i)
{
vp[((i + 1) << 3) - 2] = new Vector4(tp[i], btt, 0.0f, 1.0f);
// Additional Vector4 construction omitted for brevity
nttp[i] = new Vector2(tp[i], this.ttvp);
nts[i] = string.Format(ap[i], /* etc. */);
}
}
}
}
this.ts = nts;
this.ttp = nttp;
this.V = nv; // <- This is a property setter
}
Run Code Online (Sandbox Code Playgroud)
我不得不对此进行模糊处理,但希望它仍然清晰,可以了解正在发生的事情.
在我们的一个开发人员的机器上,在调试版本中,C#编译器删除了fixed块关闭后发生的三个分配.如果我们尝试在这些行上放置断点,断点将在应用程序启动时跳转到方法的结束括号.在fixed块和方法结束之间出现的代码也会在其他方法中被删除,但令人费解的是,并非在所有方法中都被删除.
经过一些实验,我们发现为受影响的项目启用优化会导致丢失代码.但是,这种解决方法无法进行单元测试 - 缺少代码,更改受影响项目及其测试项目的优化也无济于事.我们还发现,在最内层fixed语句中移动三个赋值是有效的 - 在检查IL时,它变得清晰.
在受影响的计算机上构建的调试DLL中(关闭优化),ap从堆栈弹出后直接出现返回操作:
IL_03a1: nop
IL_03a2: ldc.i4.0
IL_03a3: conv.u
IL_03a4: stloc.s ap
IL_03a6: ret
Run Code Online (Sandbox Code Playgroud)
这解释了为什么在stloc指令工作之前移动三个作业.在我的机器上构建的调试DLL中,返回操作发生在三个赋值之后的预期位置:
IL_03a5: nop
IL_03a6: ldc.i4.0
IL_03a7: conv.u
IL_03a8: stloc.s ap
IL_03aa: nop
IL_03ab: ldc.i4.0
IL_03ac: conv.u
IL_03ad: stloc.s tp
IL_03af: nop
IL_03b0: ldc.i4.0
IL_03b1: conv.u
IL_03b2: stloc.s vp
IL_03b4: ldarg.0
IL_03b5: ldloc.s nts
IL_03b7: stfld string[] N.B.E.B::ts
IL_03bc: ldarg.0
IL_03bd: ldloc.s nttp
IL_03bf: stfld valuetype [SharpDX]SharpDX.Vector2[] N.B.E.B::ttp
IL_03c4: ldarg.0
IL_03c5: ldloc.s nv
IL_03c7: call instance void N.B.E.B::set_V(valuetype [SharpDX]SharpDX.Vector4[])
IL_03cc: nop
IL_03cd: ret
Run Code Online (Sandbox Code Playgroud)
到目前为止,我们未能制作出一个SSCCE--这似乎只在非常具体的情况下才会出现,而且只在我们的一个项目中出现.我们检查过两台机器上都使用了相同版本的Visual Studio,.NET框架,C#编译器和MSBuild.我们检查了其他潜在的差异,如操作系统版本和更新.两台机器上的情况似乎相同(它们与笔记本电脑的型号相同).坦率地说,我们有点困惑.任何帮助将非常感激.
我的同事(其机器受到影响的开发人员)发现构建的诊断输出存在差异 - 这是 C# 编译器。我们认为 MSBuild 在预期位置(c:\Program Files (x86)\MSBuild\12.0\Bin)使用 csc.exe,但奇怪的是,它实际上是在C:\Users\[user ]\AppData\Local\Microsoft\VisualStudio\12.0\Extensions,它有一个完全不同的版本。我们不知道该编译器可执行文件是如何出现的,也不知道 MSBuild 如何引用它,但是一旦将其删除,MSBuild 就会恢复使用其主 Bin 目录中的 csc.exe 版本,并且代码将被删除现在已正确构建。
| 归档时间: |
|
| 查看次数: |
71 次 |
| 最近记录: |