The Data Initialization Problem
Before we start looking at new kinds of data such as resources, let’s look back at one of the problems confronting programmers in any language: initializing variables. What value does a variable have when you first declare it, and what happens if you try to read it before you initialize it? And how do you get an initial value into a variable? And why bother to initialize variables, anyway?
The last question is easy to answer. Take a look at control and form properties. You initialize them at design time in the Properties window. Think of the extra code if you had to initialize every Caption property of every button at run time. Initialization is so important to control and form properties that Visual Basic keeps making property pages more and more sophisticated. For example, you can initialize the strings of a ListBox control at design time, a task you had to perform at run time in early versions. All the good reasons for allowing you to initialize properties are equally good reasons for allowing you to initialize variables in code. You often want not only an initial default value but also the ability to change the default.
In some languages, uninitialized variables have a semirandom value. In C, for example, local variables (but not global or static variables) are undefined. If you want an initial value, you must give it. Fortunately for C programmers, this is easy to do. An undefined variable is a disaster waiting to happen, and careful C coders initialize their variables as close to declarations as possible. In contrast, Visual Basic always initializes all variables whenever they are declared. String variables are initialized to vbNullString, numeric variables are initialized to 0, Variants are initialized to Empty, and object variables are initialized to Nothing.
This difference fits the philosophies of C and Visual Basic. C doesn’t initialize variables to a default because local variables must be initialized at run time. This has a cost, and C doesn’t do any run-time work unless you ask for it. Undefined variables are dangerous, but that’s your problem. Visual Basic is more concerned with safety. If you declare an array of 5000 Integers, Visual Basic will initialize them all to 0 even if it takes extra run-time work to do so.
The problem for Visual Basic programmers is that 0 or Empty might not be the initial value the program needs. In C, you can combine the declaration of a variable with its initialization:
int cLastWindow = 20;
In Visual Basic, declaration and initialization are different statements:
Dim cLastWindow As Integer
cLastWindow = 20
This usually works OK for local variables, but it’s a problem for module-level (private) or global (public) variables. You must declare these in the Declarations section at the top of the module, where executable statements such as variable assignments aren’t allowed.
You need to find some other place to put the initialization statement, and that place must be reached only once—either when the module is loaded or the first time the variable is accessed. No matter how you initialize your variables, the initialization statement will be separated from the declaration in your source file, which makes initialization code difficult to maintain. If you change the declaration, you must go to a completely separate location to change the initialization, even though the two parts are logically related.
What’s needed to initialize variables is a combination declaration and initialization such as this:
Dim cLastWindow As Integer = 20
Static fFirstTime As Boolean = True
Private sExeFile As String = “VB.EXE”
Public aiCount(1 To 10) As Long = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Public ai3D(1 To 2, 1 To 3) As Long = ((1, 2), (2, 2), (2, 1))
Private perMe As TPerson = (“McKinney”, “Bruce”, 21, _
(“24 First Ave.”, “Andula”, _
“Basic”, “Cathistan”, 72948 _
) _
)
As you know, Visual Basic has no such syntax. It’s the only major computer language that doesn’t.
I really wanted to delete this whole section from the second edition of my book, but alas, version 5 offers no fixes for the biggest flaw in the Visual Basic language. Instead, it tempts us by offering the exact syntax we need in a less useful context. The new typed optional arguments allow initialization of procedure arguments:
Sub GiveMe(Optional rMoney As Double = 1000000)
Furthermore, you can also specify a type along with an initial Const value:
Const rDoubleOrNothing As Double = 2000000
These are both very fine features but little more than fluff compared to what we really need:
Private rBigBucks As Double = 8000000
Notice that the sample initializations get significantly more complex when you start dealing with arrays, multidimensional arrays, UDTs, and nested UDTs—not to mention initializing collections of arrays of classes. Needless to say, the syntax above is not the only one possible.
Initializing constants is a related problem. Of course, all constants are initialized by definition, but the limited syntax of the Const statement makes it impossible to initialize arrays, UDTs, and strings containing control characters, to mention a few common types. For example, wouldn’t it be handy to have the following constants?
Const sCrLf = Chr$(13) & Chr$(10)
Const asDays(1 To 7) = (“Sunday”, “Monday”, “Tuesday”, “Wednesday”, _
“Thursday”, “Friday”, “Saturday”)
Neither statement is legal in Visual Basic. You have to get the equivalent by declaring variables and then initializing them later, even though you have no intention of ever modifying them and would prefer that they were constants.