5. Assigning Names

Rule 12
The identifier of every globally visible class, enumeration type, type definition, function, constant, and variable in a class library is to begin with a prefix that is uniquefor the library.
Rule 13
The names of variables, constants, and functions are to begin with a lowercase letter.
Rule 14
The names of abstract data types, structures, typedefs, and enumerated types are to begin with an uppercase letter.
Rule 15
In names which consist of more than one word, the words are written together and each word that follows the first is begun with an uppercase letter.
Rule 16
Do not use identifiers which begin with one or two underscores (`_' or `__').
Rule 17
A name that begins with an uppercase letter is to appear directly after its prefix.
Rule 18
A name that begins with a lowercase letter is to be separated from its prefix using an underscore (`_').
Rule 19
A name is to be separated from its suffix using an underscore (`_').
Rec. 14
Do not use typenames that differ only by the use of uppercase and lowercase letters.
Rec. 15
Names should not include abbreviations that are not generally accepted.
Rec. 16
A variable with a large scope should have a long name.
Rec. 17
Choose variable names that suggest the usage.
Rec. 18
Write code in a way that makes it easy to change the prefix for global identifiers.
Rec. 19
Encapsulate global variables and constants, enumerated types, and typedefs in a class.

In this chapter, it is important to distinguish between identifiers and names. [See terminology 1!] The name is that part of an identifier that shows its meaning. An identifier consists of a prefix, a name, and a suffix (in that order). The prefix and the suffix are optional. A suffix is only used by tools that generate C++ code, to avoid name collisions with user-written C++ code and is not given further consideration here.

It is recommended identifiers not be extremely long, to reduce the risk for name collisions when using tools that truncate long identifiers.

The Unix command ar truncates file names that are longer than 15 characters.

Cfront normally modifies generated C-identifiers that are longer than 31 characters by truncating them and adding a hash value that is generated from the truncated part of the string.

The use of two underscores (`__') in identifiers is reserved for the compiler's internal use according to the ANSI-C standard.

Underscores (`_') are often used in names of library functions (such as "_main" and "_exit"). In order to avoid collisions, do not begin an identifier with an underscore.

One rule of thumb is that a name which cannot be pronounced is a bad name. A long name is normally better than a short, cryptic name, but the truncation problem must be taken into consideration. Abbreviations can always be misunderstood. Global variables, functions and constants ought to have long enough names to avoid name conflicts, but not too long.

Classes should be named so that "object.function" is easy to read and appears to be logical.

There are many class libraries available for purchase and there may be tens of thousands of classes in a large project!! Because of this, it is important to be careful that name collisions do not occur. One way of preventing collisions is to have strict rules for assigning names to globally visible objects (such as our use of a prefix). In this way, classes from several different class libraries may be used at the same time.

Names for the following types of objects are to be prefixed:

The use of prefixes can sometimes be avoided by using a class to limit the scope of the name. Static variables in a class should be used instead of global variables and constants, enumerated data types, and typedefs. Although nested classes may be used in C++, these give rise to too many questions (in connection with the language definition) to be able to recommend their use.

Exception to Rule 12
No exceptions.
Exception to Rule 13
No exceptions. (At times, an identifier begins with an abbreviation written in uppercase letters, to emphasize the way in which the name is used. Such an abbreviation is considered to be a prefix).
Exception to Rule 14
If the last letter in a word is in uppercase, an underscore is to be used as a word separator.
Exception to Rule 15
No exceptions.
Exception to Rule 16
No exceptions.
Exception to Rule 17
No exceptions.
Exception to Rule 18
No exceptions.
Exception to Rule 19
No exceptions.

Example 9: Exception using compound names

   const char* functionTitle = "EUA_Special";
   int currentIO_Stream = 1; // Last Character in currentIO is in uppercase!

Example 10: Choice of names

   int groupID;                    // instead of grpID
   int nameLength;                 // instead of namLn
   PrinterStatus resetPrinter;     // instead of rstprt

Example 11: Ambiguous names

   void termProcess();             // Terminate process or
                                   // terminal process?

Example 12: Names having numeric characters can cause errors which are difficult to locate.

   int I0 = 13;                    // Names with digits can be
   int IO = I0;                    // difficult to read.

Example 13: Definition of a class in the class library Emc2

   class Emc2Class
         Emc2Class();    // Default constructor
         // ...
         int id;
         // ...

Example 14: One way to avoid global functions and classes

   // Instead of declaring:
   void Emc2_myFunc1();
   void Emc2_myFunc2();
   class Emc2MyClass { /* ... */ };
   // Encapsulate the functions using an abstract class:
   class Emc2
         static void myFunc1();
         static void myFunc2();
         class MyClass { /* ... */ };
         virtual dummy() = 0;   // Trick to make the class abstract
   // Now, functions and classes may be accessed by using the scope-operator:
   Emc2::MyClass myObject;