4

... and by different I don't mean performance, debug-ability candies and so on, I am meaning different programs (programs that for the same input gives different outputs).

Take the following program:

static void Main()
{
            object obj = new object();
            WeakReference objRef = new WeakReference(obj);

            Console.Write(objRef.IsAlive);

            obj = null;
            GC.Collect();

            Console.Write(objRef.IsAlive);

            if (objRef.IsAlive)
            {

            }
            else
            {

            }
}

The program above give different results in Debug mode and Release mode, from .Net framework 4.0 onward.

In Debug the output is "TrueTrue" and in Release the output is "TrueFalse".

Note that if I remove the 'if' part at the end, the problem doesn't happen anymore.

So my first question is: What is going on here ? Why the 'if' affects the behavior of the program and make Debug and Release different ?

I know that the Debug output is not the same that the Release output, but I usually expect differences like performance optimizations, debug information, and so on ...

I think that I should expect that in all the cases for a given Input, both, the Debug and Release programs should give the same Output.

In order of not to make any assumption let me state the previous sentence as my second question:

Should I expect that in all the cases for a given Input, both, the Debug and Release programs should give the same Output ?

Obviously the answer to the second question is no, so I already make a program that is a counterexample. But also sounds very weird to me that a program is being specified outside the Language it self (by other means). That is, from a unique C# source I can get different programs i.e. programs that do different things.

But I would like to read other opinions ?

Edit: Note also that IsAlive is a property so should not have side effects.

1 Answers1

2

In a debug build or having a debugger attached the behavior of the GC and the JIT compiler changes to aid in debugging.

If you your code has 0 dependencies on the GC or JIT optimizations you will have the same behavior in debug and release. However if your code depends on GC behavior (like using WeakReference) or JIT optimizations (The biggest one I can think of is dealing with non-volatile variables in multi-threaded environments) you may get different behavior based on the way it was built or if a debugger is attached.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431