C#“是”的结构类型检查 - 奇.NET 4.0 x86的优化行为 [英] C# 'is' type check on struct - odd .NET 4.0 x86 optimization behavior

查看:139
本文介绍了C#“是”的结构类型检查 - 奇.NET 4.0 x86的优化行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:我提起的与微软连接错误报告,请为它投票!



更新2:微软已标记的bug报告固定




发布微软18 / 08/2010 17:25



这bug会被固定在
运行时的未来版本。我
怕是为时尚早如果
将在服务包或下
主要版本。




由于升级到VS2010我得到的'是'关键字一些很奇怪的行为。



下面的程序(test.cs中)当与优化(用于x86)编译时,在调试模式(86)和假编制真实输出。在编译或x64的所有值为anycpu组合给出了预期的结果,真实。



在.NET 3.5编译给出预期结果的所有组合,真实。



我用下面的批处理文件(runtest.bat)来编译和测试使用编译器的.NET架构的各种组合的代码。




  • 有其他人看到这些类型的问题在.NET 4.0?

  • 有没有其他人看到自己的计算机上的相同的行为,我跑runtests.bat时?

  • #@ $ @#$ ??

  • 是否有此?

修复

test.cs中



 使用系统; 

公共类节目
{
公共静态布尔IsGuid(对象的项目)
{
返回产品的Guid;
}

公共静态无效的主要()
{
Console.Write(IsGuid(Guid.NewGuid()));
}
}



runtest.bat



 关闭@echo 

REM用法:
REM的runTest - 与CSC.EXE x86的.NET 4.0 $ b $运行b REM的runTest 64 - 用CSC.EXE 64 .NET 4.0
REM的runTest V3.5运行 - 与CSC.EXE x86的.NET 3.5
REM的runTest V3.5 64运行 - 与运行CSC .EXE 64 .NET 3.5

组版本= v4.0.30319
组平台=框架

。对于一个%%在(%*)做(
如果%%一个==64(一套平台= Framework64)
如果%%一个==V3.5(集版本V3.5 =)


回声编译:%平台%\%版本%\csc.exe
组CSC =C:\Windows\Microsoft.NET\%平台%\%版本% \csc.exe

组做出=%CSC%/ NOLOGO / nowarn:1607 test.cs中
REM CS1607:引用程序集针对不同的处理器
REM如果发生这种情况编译使用csc64

%彩妆%/平台使用csc32 x64或x86:在86
test.exe的
回声= ^> 86

%彩妆%/平台:86 /优化
test.exe的
回声= ^> 86(优化)

%彩妆%/平台:86 /调试
test.exe的
回声= ^> 86(调试)

%彩妆%/平台:86 /调试/优化
test.exe的
回声= ^> 86(调试+优化)

%彩妆%/平台:64
test.exe的
回声= ^> 64

%彩妆%/平台:X64 /优化
test.exe的
回声= ^> 64(优化)

%彩妆%/平台:X64 /调试
test.exe的
回声= ^> 64(调试)

%彩妆%/平台:X64 /调试/优化
test.exe的
回声= ^> 64(调试+优化)

%彩妆%/平台:值为anycpu
test.exe的
回声= ^>值为anycpu

%彩妆%/平台:值为anycpu /优化
test.exe的
回声= ^>值为anycpu(优化)

%彩妆%/平台:值为anycpu /调试
test.exe的
回声= ^>值为anycpu(调试)

%彩妆%/平台:值为anycpu /调试/优化
test.exe的
回声= ^>值为anycpu(调试+优化)



测试结果



在运行runtest.bat我得到我的Win7的X64以下结果安装

 > 32的runTest V4.0 
编译:Framework\v4.0.30319\csc.exe
错=> 86
错=> 86(优化)
真=> 86(调试)
错=> 86(调试+优化)
真=> 64
真=> 64(优化)
真=> 64(调试)
真=> 64(调试+优化)
真=>值为anycpu
真=>值为anycpu(优化)
真=>值为anycpu(调试)
真=>值为anycpu(调试+优化)

> 64的runTest V4.0
编译:Framework64\v4.0.30319\csc.exe
错=> 86
错=> 86(优化)
真=> 86(调试)
错=> 86(调试+优化)
真=> 64
真=> 64(优化)
真=> 64(调试)
真=> 64(调试+优化)
真=>值为anycpu
真=>值为anycpu(优化)
真=>值为anycpu(调试)
真=>值为anycpu(调试+优化)

> 32的runTest V3.5
编译:Framework\v3.5\csc.exe
真=> 86
真=> 86(优化)
真=> 86(调试)
真=> 86(调试+优化)
真=> 64
真=> 64(优化)
真=> 64(调试)
真=> 64(调试+优化)
真=>值为anycpu
真=>值为anycpu(优化)
真=>值为anycpu(调试)
真=>值为anycpu(调试+优化)

> 64的runTest V3.5
编译:Framework64\v3.5\csc.exe
真=> 86
真=> 86(优化)
真=> 86(调试)
真=> 86(调试+优化)
真=> 64
真=> 64(优化)
真=> 64(调试)
真=> 64(调试+优化)
真=>值为anycpu
真=>值为anycpu(优化)
真=>值为anycpu(调试)
真=>值为anycpu(调试+优化)



TL;博士


解决方案

我的工作了失败同样的方式类似的例子:

 使用系统;使用System.Runtime.CompilerServices 
;

公共类节目{
静态无效的主要(){
Console.Write(验证(Test.Create()));
到Console.ReadLine();
}
//[MethodImpl(MethodImplOptions.NoInlining)
静态布尔验证(IDisposable的项目){
返回产品测试;
}
结构测试:IDisposable的{
公共无效的Dispose(){}
公共静态测试的Create(){返回新测试(); }
}
}



这是一个JIT优化器的bug。不能完全把手指就可以了,它在很大程度上优化了代码。但它看起来对我来说,它会遇到麻烦时,它优化了装箱转换了。非常严重的错误,坦率地说。






此bug已修复,我不能再瑞普它。我目前clrjit.dll的版本是4.0.30319.237日期为5月17日2011年。我不能告诉正是更新修复它。我得到了2011年8月5日的更新clrjit.dll修订235 4月12日的最新安全更新,这将是最早的。


Update: I have filed a bug report with Microsoft Connect, please vote for it!

Update 2: Microsoft have marked the bug report as fixed

Posted by Microsoft on 18/08/2010 at 17:25

This bug will be fixed in a future version of the runtime. I'm afraid it's too early to tell if that will be in a service pack or the next major release.

Since upgrading to VS2010 I'm getting some very strange behavior with the 'is' keyword.

The program below (test.cs) outputs True when compiled in debug mode (for x86) and False when compiled with optimizations on (for x86). Compiling all combinations in x64 or AnyCPU gives the expected result, True.

All combinations of compiling under .NET 3.5 give the expected result, True.

I'm using the batch file below (runtest.bat) to compile and test the code using various combinations of compiler .NET framework.

  • Has anyone else seen these kind of problems under .NET 4.0?
  • Does everyone else see the same behavior as me on their computer when running runtests.bat?
  • #@$@#$??
  • Is there a fix for this?

test.cs

using System;

public class Program
{
    public static bool IsGuid(object item)
    {
        return item is Guid;
    } 

    public static void Main()
    {
        Console.Write(IsGuid(Guid.NewGuid()));
    }
}

runtest.bat

@echo off

rem Usage:
rem   runtest         -- runs with csc.exe x86 .NET 4.0
rem   runtest 64      -- runs with csc.exe x64 .NET 4.0
rem   runtest v3.5    -- runs with csc.exe x86 .NET 3.5
rem   runtest v3.5 64 -- runs with csc.exe x64 .NET 3.5

set version=v4.0.30319
set platform=Framework

for %%a in (%*) do (
  if "%%a" == "64" (set platform=Framework64)
  if "%%a" == "v3.5" (set version=v3.5)
)

echo Compiler: %platform%\%version%\csc.exe
set csc="C:\Windows\Microsoft.NET\%platform%\%version%\csc.exe"

set make=%csc% /nologo /nowarn:1607 test.cs
rem CS1607: Referenced assembly targets a different processor
rem This happens if you compile for x64 using csc32, or x86 using csc64

%make% /platform:x86
test.exe
echo  =^> x86

%make% /platform:x86 /optimize
test.exe
echo  =^> x86 (Optimized)

%make% /platform:x86 /debug
test.exe
echo  =^> x86 (Debug)

%make% /platform:x86 /debug /optimize
test.exe
echo  =^> x86 (Debug + Optimized)

%make% /platform:x64
test.exe
echo  =^> x64

%make% /platform:x64 /optimize
test.exe
echo  =^> x64 (Optimized)

%make% /platform:x64 /debug
test.exe
echo  =^> x64 (Debug)

%make% /platform:x64 /debug /optimize
test.exe
echo  =^> x64 (Debug + Optimized)

%make% /platform:AnyCPU
test.exe
echo  =^> AnyCPU

%make% /platform:AnyCPU /optimize
test.exe
echo  =^> AnyCPU (Optimized)

%make% /platform:AnyCPU /debug
test.exe
echo  =^> AnyCPU (Debug)

%make% /platform:AnyCPU /debug /optimize
test.exe
echo  =^> AnyCPU (Debug + Optimized)

Test Results

When running the runtest.bat I get the following results on my Win7 x64 install.

> runtest 32 v4.0
Compiler: Framework\v4.0.30319\csc.exe
False => x86
False => x86 (Optimized)
True => x86 (Debug)
False => x86 (Debug + Optimized)
True => x64
True => x64 (Optimized)
True => x64 (Debug)
True => x64 (Debug + Optimized)
True => AnyCPU
True => AnyCPU (Optimized)
True => AnyCPU (Debug)
True => AnyCPU (Debug + Optimized)

> runtest 64 v4.0
Compiler: Framework64\v4.0.30319\csc.exe
False => x86
False => x86 (Optimized)
True => x86 (Debug)
False => x86 (Debug + Optimized)
True => x64
True => x64 (Optimized)
True => x64 (Debug)
True => x64 (Debug + Optimized)
True => AnyCPU
True => AnyCPU (Optimized)
True => AnyCPU (Debug)
True => AnyCPU (Debug + Optimized)

> runtest 32 v3.5
Compiler: Framework\v3.5\csc.exe
True => x86
True => x86 (Optimized)
True => x86 (Debug)
True => x86 (Debug + Optimized)
True => x64
True => x64 (Optimized)
True => x64 (Debug)
True => x64 (Debug + Optimized)
True => AnyCPU
True => AnyCPU (Optimized)
True => AnyCPU (Debug)
True => AnyCPU (Debug + Optimized)

> runtest 64 v3.5
Compiler: Framework64\v3.5\csc.exe
True => x86
True => x86 (Optimized)
True => x86 (Debug)
True => x86 (Debug + Optimized)
True => x64
True => x64 (Optimized)
True => x64 (Debug)
True => x64 (Debug + Optimized)
True => AnyCPU
True => AnyCPU (Optimized)
True => AnyCPU (Debug)
True => AnyCPU (Debug + Optimized)

tl;dr

解决方案

I worked up a similar example that fails the same way:

using System;
using System.Runtime.CompilerServices;

public class Program {
  static void Main() {
    Console.Write(Verify(Test.Create()));
    Console.ReadLine();
  }
  //[MethodImpl(MethodImplOptions.NoInlining)]
  static bool Verify(IDisposable item) {
    return item is Test;
  }
  struct Test : IDisposable {
    public void Dispose() { }
    public static Test Create() { return new Test(); }
  }
}

It is a JIT optimizer bug. Can't quite put the finger on it, it optimizes the code heavily. But it looks to me like it gets in trouble when it optimizes the boxing conversion away. Pretty serious bug, frankly.


This bug has been fixed, I can no longer repro it. My current version of clrjit.dll is 4.0.30319.237 dated May 17th 2011. I can't tell exactly what update repaired it. I got a security update on Aug 5th 2011 that updated clrjit.dll to revision 235 with a date of Apr 12, that would be the earliest.

这篇关于C#“是”的结构类型检查 - 奇.NET 4.0 x86的优化行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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