VB6 beginners tutorial - Learn VB6

Advanced VB6 tutorial - Learn Advanced VB6

VB .NET - Learn Visual Basic .NET

Systems Analysis - System analysis and Design tutorial for Software Engineering

You are here: Visual Basic > Advanced VB6 tutorial > Chapter 20

Applications and Styles

This discussion to this point has focused on the mechanics of how conditional compilation enables you to selectively include and exclude parts of your code from the compiled version of a project. Now the focus changes to some applications of these concepts. What follows is hardly an exhaustive list of all the possibilities, but it should at least suggest some ways to use the preprocessor to your advantage.

Using Debug Mode

Conditional compilation makes it easier to remove debugging tests from your code prior to building a release version of a project. Rather than having to manually search and remove (or comment out) tests that may be scattered in multiple modules, you can place your debug code in conditional compiler blocks:

Dim BuggyVariable as String
‘ ... processing occurs
#If TESTING = 1 Then
‘ see if THIS is where BuggyVariable blew up
MsgBox "Current value of BuggyVariable" " &
#End If

Naturally, you don’t want this to appear in a released product. The key is to define a constant that will be True only when you are debugging, and False otherwise. Visual C++ includes a predefined compiler constant that serves just such a purpose, but Visual Basic requires you to create your own "Debug mode" constant. Recall that there are three ways to define a compiler constant. You could define

#Const TESTING = 1

in every module with debug code, and then wrap your tests in the following:

#End If

Of course, this requires you to manually alter each module so that TESTING is no longer defined as 1 when it is time to build a release. One of the reasons to use conditional compilation in the first place is to cut down on that kind of drudgery. Therefore, defining the constant via #Const probably isn’t the best choice unless your debugging tests are confined to a single module.

Defining a Public compiler constant, either via the Project Properties dialog box or on the command line, defines a constant for the entire project. Of course, if you use the Project Properties dialog box, you must remember to change the value of TESTING (for example, TESTING = 0) before building your release. This approach has the advantage of leaving you with only one place to make the change. Still, it is possible to forget, especially if you don’t visit the Project Properties dialog box regularly. This approach is less risky than having to track down #Const in multiple source files, but there is still a chance that you will release a project that includes your debug code.

What about the command line? Because you have to explicitly define your Public compiler constant with the /d switch before beginning each debug session, this is less convenient than setting the constant with the Project Properties dialog box. However, it also means that you’re extremely unlikely ever to ship a version of a project with your debug tests accidentally enabled.

This raises another issue, however: What happens to a conditional compiler test when a compiler constant is undefined? If you leave the conditional tests in place after eliminating the definition of a constant, you might expect to see some kind of preprocessor error message or warning. In fact, you won’t get one.

Recall that preprocessor constants are treated as Variants. If a Variant hasn’t been initialized, it has the value Empty. Now, assume that the RELEASEMODE constant in this example has not yet been defined:

MsgBox "But I thought this code wouldn’t be compiled!"
#End If

In this case, the message box will appear. A Variant containing Empty is treated as 0, and Not 0 evaluates to True. This means that the message box pops up even if you haven’t assigned a value to RELEASEMODE.

Because you can’t rely on a compiler warning or preprocessor error message to inform you of your mistake (there is no Option Explicit for compiler constants), it is a good idea to take this default behavior into account when you code your tests to avoid surprises. Always test the compiler constant used to wrap your debug code for a non-zero value. (That is, never rely on a test that reduces to "MYCONSTANT = 0".) If you use the command line switch to define your debug compiler constant, this will make it impossible to accidentally compile your debug tests into a release.

From a mechanical standpoint, there is nothing more to know about the process of conditional compilation. After you understand the rules for defining and testing constants, all that is left is to dream up new ways to apply them. The rest of this chapter suggests a few ideas to get you started.

Comparing Algorithms

If you are not sure which algorithm is best suited to a procedure, implement the ones you want to compare in a conditional block. For example:

#Const SortMethod = 1
#If SortMethod = 1
‘ Insertion Sort
#Else If SortMethod = 2
‘ Bubble Sort
#Else If SortMethod = 3
‘ QuickSort
‘ #Else If etc.
#End If

The quantity and state of the data it manipulates may affect the performance of an algorithm. Insertion sorts are fast with small lists, for example, but performance deteriorates as the size of the list increases. If a list is already nearly sorted, a bubble sort can be quite fast.

Conditional compilation to support different algorithms makes it easier for you to test different approaches to programming problems. Depending on the completeness of your implementation, you may also find it useful to be able to adapt your program to the demands of different data sets just by changing the value of a compiler constant and recompiling.

Feature Sets

The same body of code can support different combinations of features. You may want to use the same interface for a database program, for example, but employ it with different data engines. Using conditional compilation, you could produce separate versions of your program for DAO, RDO, and ODBC.

Unlike the database scenario, which requires selecting one approach from among competing alternatives, you can also take an additive approach. If you add fax support to your program, but you only want it to be included in the releases 2.0 and up, you can still produce a 1.0 EXE from your source, as follows:

#If ReleaseNumber >= 2 Then
‘ fax support
#End If

Just make sure that you specify #Const ReleaseNumber = 1 when you need to generate a 1.0 copy of your program. It is no match for a full-blown version control system, but conditional compilation can serve as a limited VCS.

Client Specific

If you provide the same program to multiple clients who require slightly different features, you can implement these features in a common body of code by wrapping the client-specific features in conditional compiler blocks that compare a constant to the client name:

#If ClientName = "Clinton" Then
‘ ingenious code that cripples the Republican party,
‘ except for that pesky Whitewater bug
#End If
#If ClientName = "Dole"
‘ ingenious code that cripples the Democratic party,
‘ except for that annoying 1996 bug
#End If


<< Previous | Contents | Next (Chapter 21) >>

Home | About Us | Privacy Policy | Contact Us

Copyright © | All Rights Reserved