Note that there are some explanatory texts on larger screens.

plurals
  1. POCan C# 'is' operator suffer under release mode optimization on .NET 4?
    text
    copied!<p>Below is a simple test fixture. It succeeds in Debug builds and fails in Release builds (VS2010, .NET4 solution, x64):</p> <pre><code>[TestFixture] public sealed class Test { [Test] public void TestChecker() { var checker = new Checker(); Assert.That(checker.IsDateTime(DateTime.Now), Is.True); } } public class Checker { public bool IsDateTime(object o) { return o is DateTime; } } </code></pre> <p>It seems code optimization wreaks some havoc; if I disable it on the Release build, it works as well. That was rather puzzling to me. Below, I've used ILDASM to disassemble the 2 versions of the build:</p> <p>Debug IL:</p> <pre><code>.method public hidebysig instance bool IsDateTime(object o) cil managed { // Code size 15 (0xf) .maxstack 2 .locals init (bool V_0) IL_0000: nop IL_0001: ldarg.1 IL_0002: isinst [mscorlib]System.DateTime IL_0007: ldnull IL_0008: cgt.un IL_000a: stloc.0 IL_000b: br.s IL_000d IL_000d: ldloc.0 IL_000e: ret } // end of method Validator::IsValid </code></pre> <p>Release IL:</p> <pre><code>.method public hidebysig instance bool IsDateTime(object o) cil managed { // Code size 10 (0xa) .maxstack 8 IL_0000: ldarg.1 IL_0001: isinst [mscorlib]System.DateTime IL_0006: ldnull IL_0007: cgt.un IL_0009: ret } // end of method Validator::IsValid </code></pre> <p>It seems a store and load is optimized away. Targeting earlier versions of the .NET framework made the problem go away, but that may just be a fluke. I found this behaviour somewhat unnerving, can anybody explain why the compiler would think it safe to do an optimization that produces different observable behaviour?</p> <p>Thanks in advance.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload