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
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.
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.
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.
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.
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+ ");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With