VB.NET Preprocessor Directives

12,706

Turns out, it's not all of VB.NET that's broken - just the CodeDomProvider (which both ASP.NET and Snippet Compiler use).

Given a simple source file:

Imports System
Public Module Module1
    Sub Main()
       #If DEBUG Then
          Console.WriteLine("Debug!")
       #End If

       #If Not DEBUG Then
          Console.WriteLine("Not Debug!")
       #End If
    End Sub
End Module

Compiling with vbc.exe version 9.0.30729.1 (.NET FX 3.5):

> vbc.exe default.vb /out:out.exe
> out.exe
  Not Debug!

That makes sense...I didn't define DEBUG, so it shows "Not Debug!".

> vbc.exe default.vb /out:out.exe /debug:full
> out.exe
  Not Debug!

And, using CodeDomProvider:

Using p = CodeDomProvider.CreateProvider("VisualBasic")
   Dim params As New CompilerParameters() With { _
      .GenerateExecutable = True, _
      .OutputAssembly = "out.exe" _
   }
   p.CompileAssemblyFromFile(params, "Default.vb")
End Using

> out.exe
Not Debug!

Okay, again - that makes sense. I didn't define DEBUG, so it shows "Not Debug". But, what if I include debug symbols?

Using p = CodeDomProvider.CreateProvider("VisualBasic")
   Dim params As New CompilerParameters() With { _
      .IncludeDebugInformation = True, _
      .GenerateExecutable = True, _
      .OutputAssembly = "C:\Users\brackett\Desktop\out.exe" _
   }
   p.CompileAssemblyFromFile(params, "Default.vb")
End Using

> out.exe
Debug!
Not Debug!

Hmm...I didn't define DEBUG, but maybe it defined it for me? But if it did, it must have defined it as "1" - because I can't get that behavior with any other value. ASP.NET, using the CodeDomProvider, must define it the same way.

Looks like the CodeDomProvider is tripping over VB.NET's stupid psuedo-logical operators.

Moral of the story? #If Not is not a good idea for VB.NET.


And now that source is available, I can verify that it does actually set it equal to 1 as I expected:

if (options.IncludeDebugInformation) {
      sb.Append("/D:DEBUG=1 ");
      sb.Append("/debug+ ");
}
Share:
12,706
Mark Brackett
Author by

Mark Brackett

Updated on June 17, 2022

Comments

  • Mark Brackett
    Mark Brackett almost 2 years

    Why doesn't #IF Not DEBUG work the way I'd expect in VB.NET?

    #If DEBUG Then
       Console.WriteLine("Debug")
    #End If
    
    #If Not DEBUG Then
       Console.WriteLine("Not Debug")
    #End If
    
    #If DEBUG = False Then
       Console.WriteLine("Not Debug")
    #End If
    ' Outputs: Debug, Not Debug
    

    But, a manually set const does:

    #Const D = True
    #If D Then
       Console.WriteLine("D")
    #End If
    
    #If Not D Then
       Console.WriteLine("Not D")
    #End If
    ' Outputs: D
    

    And, of course, C# has the expected behavior as well:

    #if DEBUG
        Console.WriteLine("Debug");
    #endif
    
    #if !DEBUG
        Console.WriteLine("Not Debug");
    #endif
    // Outputs: Debug