Coding: Variables

Variables local to any smaller scope than the current function should generally be avoided. They introduce too many additional places to look when you need to know what datatype something is.

Hungarian Notation is in essence a form of very brief commenting. Thus, just like with regular comments, it must be used correctly or not at all! Recall that in C, an array is essentially a pointer, and therefore should be named as a pointer, not as the type it points to. Also, under operating systems that make you deal with this hassle, remember to include in the naming of all pointers, whether it is a near or far (aka short or long) pointer.

Another naming convention, which may be used or not but should be absolutely consistent throughout the program or library, is Scope Prefixing. This means to prefix variable names with one prefix if they are global (i.e., across files), another if modular (i.e., within that one file), another for parameters to the current function, and another if static but local in scope. (The obvious choices are G, M, P, and S.) Variables local in scope to the current function, and not static, should be left without such prefixes. If you use variables local to an "if" or a loop (which are generally a bad idea), prefix them with another one (possibly L); if they are also static, use both. If used, this prefix should precede any Hungarian Notation prefixes, which are (conveniently) in the opposite case to what I have used here, to avoid confusion.

On the other claw, Hungarian Notation and Scope Prefixing are useful mainly when the file, function, or other scope, is very large. See the section on size, which can help reduce the need for these kluges.

Variable names should be meaningful at a glance, even without Hungarian Notation or Scope Prefixing. For instance, do not use "cxClient", depending on the "cx" to tell us it's a count in the horizontal direction, but rather, use something like "iClientPixelsWide", "iCliPixWid", "iPixWid", etc. (Yes, I know Charles Petzold uses names like cxClient, but I have already dared disagree with him in earlier parts. Don't be a slave to his conventions -- or mine.)

The only standard for the storage size of an "int", is that it is the same size as a pointer. On some platforms, this is two bytes; on others, it is four; on some, it can be varied with compiler options (such as memory models, on the PC). Therefore, avoid the use of int (including unsigned int), except when ensuring that it matches the size of a pointer. Instead, use long or short, as appropriate; the standards for the sizes of these are not absolute either, but they are much more stable -- almost everywhere, shorts are two bytes and longs four.

Variables should be declared one per line, in alphabetical order (IGNORING any prefixes), and be followed (or topped) by a comment. It is highly preferable to use a following comment, restricted to the rest of the line, so that the variables can be sorted without displacing comments. To do this, it is useful to line them up according to the MEANINGFUL parts of the name (that is, the parts PAST any Scope/Hungarian/whatever prefixes).

It is also good aesthetics to ensure that the "type" and "name" columns are clearly separated (i.e., at least one column of pure blank space; I personally prefer at least two), and to line up the comments as well, also clearly separated from the names.

For example:

      BYTE   pbFlags[3];   // flags -- see STKFLGS.H for meanings
      short   nPortSize;   // total size of portfolio
      char   szSymbol[6];  // ticker symbol of current issue
      char    cType;       // ticker type: B/F/I/O/S

This same construction can also be used on function argument lists.