_
' or `__
').
_
').
_
').
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:
typedef
s, enum
s,
struct
s, union
s, etc.)
#define
)
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.
const char* functionTitle = "EUA_Special"; int currentIO_Stream = 1; // Last Character in currentIO is in uppercase!
int groupID; // instead of grpID int nameLength; // instead of namLn PrinterStatus resetPrinter; // instead of rstprt
void termProcess(); // Terminate process or // terminal process?
int I0 = 13; // Names with digits can be int IO = I0; // difficult to read.
class Emc2Class { public: Emc2Class(); // Default constructor // ... private: int id; // ... };
// Instead of declaring: void Emc2_myFunc1(); void Emc2_myFunc2(); class Emc2MyClass { /* ... */ }; // Encapsulate the functions using an abstract class: class Emc2 { public: static void myFunc1(); static void myFunc2(); class MyClass { /* ... */ }; private: virtual dummy() = 0; // Trick to make the class abstract }; // Now, functions and classes may be accessed by using the scope-operator: Emc2::myFunc1(); Emc2::myFunc2(); Emc2::MyClass myObject;