Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VB.NET Preprocessor Directives

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
like image 898
Mark Brackett Avatar asked Oct 02 '09 19:10

Mark Brackett


People also ask

What are preprocessor directives in VB net?

Preprocessor directives are lines of the source file where the first non-whitespace character is # , which distinguishes them from other lines of text. The effect of each preprocessor directive is a change to the text and the result is a transformation of the text that does not contain the directives nor comments.

What is preprocessor directive with example?

Preprocessor directives can be defined in source code or in the common line as argument during compilation. Examples for preprocessing directives that can be used in C# include: #define and #undef: To define and undefine conditional compilation symbols, respectively.

Which pre directive is used to specify a region in VB net?

Remarks. Use the #Region directive to specify a block of code to expand or collapse when using the outlining feature of Visual Studio IDE. You can place, or nest, regions within other regions to group similar regions together.

What is the use of preprocessor directive?

Preprocessor directives, such as #define and #ifdef , are typically used to make source programs easy to change and easy to compile in different execution environments. Directives in the source file tell the preprocessor to take specific actions.


1 Answers

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+ ");
}
like image 91
Mark Brackett Avatar answered Sep 24 '22 02:09

Mark Brackett