views:

643

answers:

4

Are Debug.Assert/Debug.Fail automatically conditionally compiled #if "DEBUG"? Or is it more like if there is no debugger attached (even in release) it just doesn't do much of anything? If so, are there performance implications of leaving them in your code? Or are they really not meant to be in production code, only test or Conditional code?

+7  A: 

No, the whole call, incuding any expression evaluation is removed from compilation if the symbol isn't defined. This is very important - if there are any side-effects in the expression, they won't occur if DEBUG isn't defined. Here's a short but complete program to demonstrate:

using System;
using System.Diagnostics;

class Test
{
    static void Main()
    {
        int i = 0;
        Debug.Assert(i++ < 10);
        Console.WriteLine(i);
    }
}

If DEBUG is defined this prints out 1, otherwise it prints 0.

Due to this kind of behaviour, you can't have an out parameter on a conditionally-compiled method:

using System;
using System.Diagnostics;

class Test
{
    static void Main()
    {
        int i ;
        MethodWithOut(out x);
    }

    [Conditional("FOO")]
    static void MethodWithOut(out int x)
    {
        x = 10;
    }
}

This gives the error:

Test.cs(13,6): error CS0685: Conditional member 'Test.MethodWithOut(out int)' cannot have an out parameter

Jon Skeet
+2  A: 

The Debug.Assert/Fail API's contain a ConditionalAttribute attribute with the value "DEBUG" like so

[Conditional("DEBUG")]
public void Assert(bool condition)

The C# and VB compiler will only actually include a call to the is method if the constant DEBUG is defined when the method call is compiled in code. If it's no there, the method call will be ommitted from the IL

JaredPar
A: 

Yes, pretty much. The Debug methods are decorated with the [Conditional("DEBUG")] attribute, so calls to Debug methods won't be compiled into the IL if the DEBUG symbol is defined.

More info on ConditionalAttribute at MSDN.

cxfx