Rule: the names of variables and functions are to begin with a lowercase letter.
Rule: the names of types and constants are to begin with a capital letter.
Rule: if a name contain more than one word the words are written together and each word after the first
begins with a capital letter. If the last character of a word is uppercase, then an underscore character ('_')
is allowed to separate it from the next word.
Rule: names are not to begin with an underscore ('_'), as leading underscores are often used internally
by compilers and system libraries. For the same reason, names must not contain two consecutive underscores ('__').
Rule: in C++, names of class member variables are to end with an underscore ('_'). (This character is considered
a suffix and not part of the name.)
Rec.: use the prefix 'gv' for global variables.
Rec.: use an active verb to start function names, a noun for the rest.
Rec.: access methods that set attributes should named with the verb prefix "set" followed
by the attribute name (or an equivalent name).
Rec.: access methods that return attribute values should be named with the verb prefix "get"
followed by the attribute name (or an equivalent name). A valid alternative is to name the access method simply
with the name of the attribute itself.
Identifiers (i.e. names of variable, functions, types and so on) should be descriptive but concise. Good names
make code easier to read and understand, and reduce the need for comments. It is not always easy to pick up a good
name for an object and, like much else in programming, it's somewhat more art than science. There are a few guidelines
that have been found useful in practice though.
It is better to use longer names for public objects like constants, global variables, types and functions, and
shorter names for locals and other objects declared with limited scope (e.g. in C or C++ a static function that
is only declared and used within an implementation module). The main reason is that globals can appear everywhere
in a program, even far away from their declaration, so the name should convey enough information to avoid a lookup
or search. Also names with a wide scope are more prone to collisions, and longer names help solve that problem
too.
On the other side it is safe to use short names for locals and in fact long names here can have an adverse effect
and make the code less readable.
A few one-letter identifiers are so common that they can be used as is without worrying about further clarifications, such as c for characters, i and j for loop indices, p and q for pointers or s for strings. Here is an example of overkill usage of long names:
char * fillString( char * theString, char fillCharacter ) { int charIndex; charIndex = 0; while( theString[ charIndex ] != '\0' ) { theString[ charIndex++ ] = fillCharacter; } return theString; }
An implementation using shorter names can be easier to read:
/* Fill string s with character c */ char * fillString( char * s, char c ) { int i; i = 0; while( s[i] != '\0' ) { s[i++] = c; } return s; }
The following shows an unfortunate name choice:
char * convertToUppercase( char * s ) { char i; // Not a good choice: normally i denotes an integer // ... }
When looking at the body of the function, most programmers will assume i to be an integer.
Considering the variety of different names that appear in a program, it is very useful to establish a convention
that allows the reader to get extra information from an identifier. Common practices such as writing C preprocessor
macros in all capitals are good, but not good enough for large projects, which demand for a stricter set of rules.
Rule: the names of variables and functions are to begin with a lowercase letter,
Rule: the names of types and constants are to begin with a capital letter.
Rule: if a name contain more than one word the words are written together and each word after the first
begins with a capital letter. If the last character of a word is uppercase, then an underscore character ('_')
is allowed to separate it from the next word.
Rule: names are not to begin with an underscore ('_'), as leading underscores are often used internally
by compilers and system libraries. For the same reason, names must not contain two consecutive underscores ('__').
Rule: in C++, names of class member variables are to end with an underscore ('_'). (This character is considered
a suffix and not part of the name.)
Rec.: use the prefix 'gv' for global variables.
Of course nothing prevents you from using even stricter conventions, such as using prefixes for local parameters and function arguments too.
Function names should start with a verb that describes the action performed by the function. In many cases it is useful to specify the target of the action after the verb, as the verb might ambiguously refer to more than one target:
int remove( ... ); // Target not specified... remove what? int removeDirectory( ... ); // Much better: function behavior is clearly stated
Sometimes, it is the verb that leaves room to different interpretations. The expression:
if( o.checkError() || o.checkEmpty() ) ...
doesn't tip the reader on the meaning of the return value, while the form:
if( o.hasErrors() || o.isEmpty() ) ...
is a lot more readable and does not require a documentation lookup.
It is good practice not to expose class variables in public interfaces, but rather to declare them private and provide access methods only if necessary. (This allows more freedom in changing an implementation without having to change the corresponding public interface.)
Access methods benefit a lot from a consistent and uniform naming convention. For setting the value of a variable the preferred form is using the action set followed by the variable name; for reading, get is used instead. If the access methods correspond directly to an attribute of the class, it is possible to eliminate the get prefix altogether in the reading method, as the shorter form is also natural and readable. So for example we can have:
class File { public: Date & getDate() const; void setDate( const Date & date ); int size() const; // Ok, getSize() is also possible private: Date date_; int size_; };
and be able to write expressions such as:
if( f.size() > 100 ) ...
which are perfectly readable.
Rec.: use an active verb to start function names, a noun for the rest.
Rec.: access methods that set attributes should named with the verb prefix "set" followed
by the attribute name (or an equivalent name).
Rec.: access methods that return attribute values should be named with the verb prefix "get"
followed by the attribute name (or an equivalent name). A valid alternative is to name the access method simply
with the name of the attribute itself.
Teams usually contain people with different backgrounds and experiences, and identifiers should not depend too much on specific culture. In particular, abbreviations that are too cryptic or that require a better than average knowledge of a foreign language can be difficult for some team members and are better avoided. It is often said that names that cannot be pronounced are bad names: this is usually true but does not include all of the bad names!
Here are some examples of valid and invalid declarations:
const char * DatabaseFilename = "foo.db"; const int MaxUsers = 10; typedef struct { int x; int y; } Point; typedef char * pchar; // No, type must begin with a capital letter void doSomething( void ); void dosomethingelse( void ); // No, words must begin with a capital letter int getBIOS_Id( void ); // Ok, underscore used after a capital letter int nusers; // Warning, recognizing "n"+"users" may not be immediate for everyone int processId; int pid; // This is ok too, a very common identifier
Copyright (c) 2003 Alessandro Scotti. All rights reserved.