Variable prefixes
Much of the confusion in current Hungarian variations comes from trying to make the prefix do too many conflicting things. At various times, I’ve seen the prefix used to indicate several different concepts. Even if you don’t buy into Hungarian, any naming convention must deal with some of the following
elements:
-
The purpose of the variable. Is the variable used as a handle, a Boolean flag, a bit flag (an array of bits), an index, a count, an ordinal, a string, or an ID? Generally, this is the most useful piece of information you can provide, and it’s language independent. A handle is a handle, regardless of the language.
-
The data type of the variable. This information is usually irrelevant because the data type is implied by the purpose. Furthermore, the data type is language specific. If you design your naming convention for a language that supports signed and unsigned types (C and most variations of Pascal), the convention becomes irrelevant for languages that have only signed integers (Basic and FORTRAN). And if you use specific features of your language (such as C’s typedef) to rename standard types, those names will be irrelevant in languages that don’t let you rename types (most languages). If you’re familiar with the Windows API, you’re sensing that I don’t think much of its naming conventions. Right you are. A good deal of Chapter 2 will be spent telling you how to translate these names into something intelligible to Basic. The naming conventions proposed here ignore the data type.
-
The context of the variable. Generally, this means using a modifier indicating that the variable is in an array or a collection. Languages that support pointers require a modifier to distinguish a pointer to a variable from the variable itself. You can use a count modifier to indicate a count of variables. For example, if the modifier h is for a handle, a is for an array, p is for a pointer, and c is for a count, then you could have an ah (an array of handles), a ph (a pointer to a handle), or a ch (a count of handles).
-
The scope of the variable. Some conventions clearly distinguish variables that are local, global, or somewhere in between (module-level in Visual Basic). Usually, local is assumed to be the default, requiring no modifier, and g is used as a prefix modifier for globals.
You could use m as a prefix modifier for module-level variables (as the Visual Basic convention does). This isn’t a bad idea in principle, but in practice I don’t find it very useful. I don’t use globals often, and the distinction between local and module-level variables is usually clear from the context. Also, it would be easy to get carried away with distinguishing between static and normal locals or between fixed and dynamic arrays. You could go further and add prefix letters to distingish between ByVal and ByRef, to indicate the subtypes within variants, and to show whether the moon was full when the code was written.
-
The modifiability of the variable. Many conventions distinguish constants from variables, usually by making constants all uppercase.
I don’t find this distinction very useful. A constant can be identified when necessary by its name and the context. If clr is the prefix for a color, it’s pretty clear that clrTitle is a variable and clrRed is a constant. In addition, if you want to make the title red by assigning clrRed to clrTitle, it doesn’t make much difference whether clrRed is a variable or a constant.
What I’m creating here is a more portable Hungarian that works for Basic. I often don’t care what type a variable has when I use it; I’m much more interested in whether a handle is a handle to a window, a file, or a GDI object than in what data type it is. I use integers for different purposes: counts, indexes, handles, ordinals, and bit fields. Whether they are Longs or Integers usually doesn’t matter after the declaration. If I need to know, I can always go back to the declaration and check.
The point of Hungarian is not to be an absolute standard for everyone but to be standard across a given department, project, program, or, in this case, book. I’ve used the conventions defined in Table 1-2 throughout (consistently, I hope).
Some prefixes modify other prefixes. For example, acmd is an array of buttons, ccmd is a count of buttons, and ncmd is a collection of buttons. Strict Hungarian always uses c as a modifier. You could use ciWindow as a count of indexes to windows or chWindow as a count of handles to windows, but I often find that I can make the meaning clearer by omitting the second part of the prefix. If I’m counting windows, cWindow is sufficient.
I’ll introduce and explain some additional conventions later in the book. In particular, some of the new object-oriented features of Visual Basic require further discussion and variations.
Prefix |
Variable or Object |
i |
integer index (type Integer or Long) |
h |
handle |
ord |
ordinal (a numeric identification code used when the specific value is unimportant except to distinguish the variable from others) |
x, y |
x and y coordinates of points |
dx, dy |
delta (or distance) in terms of x and y coordinates (dx is width, dy is height) |
f |
Boolean |
af |
bit flag (an array of Booleans represented by bits) |
r |
real number (either Single or Double) |
b |
Byte |
v |
Variant |
cur |
Currency |
time |
time |
date |
Date |
dt |
Date and time combined |
s |
String |
p |
pointer (Long variable from or for an API function) |
cmd |
button |
chk |
check box |
txt |
text box |
pb |
picture box |
pic |
picture |
lst |
list box |
cbo |
combo box |
lbl |
label |
mnu |
menu |
tmr |
timer |
opt |
option button (radio button) |
c |
count |
A |
array |
N |
collection |
Table 1-2. Hardcore Hungarian for variables.