Name Conventions
- Rule: Stay out of reserved names
The standard reserves a number of identifier classes, most notably _** [17.4.3.1.2]:
Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
Using _** is commonly used for CPP guards (
_FOO_HH_
), private members (_foo
), and internal functions (_foo ()
): don’t.- Rule: Name your classes
LikeThis
Class should be named in mixed case; for instance
Exp
,StringExp
,TempMap
,InterferenceGraph
etc. This applies to class templates. See CStupidClassName.- Rule: Name public members
like_this
No upper case letters, and words are separated by an underscore.
- Rule: Name private/protected members
like_this_
It is extremely convenient to have a special convention for private and protected members: you make it clear to the reader, you avoid gratuitous warnings about conflicts in constructors, you leave the “beautiful” name available for public members etc. We used to write
like_this
, but this goes against the standard, see Stay out of reserved names.For instance, write:
class IntPair { public: IntPair(int first, int second) : first_(first) , second_(second) { } protected: int first_, second_; }
See CStupidClassName.
- Rule: Name your
using
type aliasfoo_type
When declaring a
using
type alias, name the typefoo_type
(where foo is obviously the part that changes). For instance:using map_type = std::map<const symbol, Entry_T>; using symtab_type = std::list<map_type>;
We used to use
foo_t
, unfortunately this (pseudo) name space is reserved by POSIX.- Rule: Name the parent class
super_type
It is often handy to define the type of “the” super class (when there is a single one); use the name
super_type
in that case. For instance most Visitors of the AST start with:class TypeChecker: public ast::DefaultVisitor { public: using super_type = ast::DefaultVisitor; using super_type::operator(); // ...
(Such
using
clauses are subject to the current visibility modifier, hence thepublic
beforehand.)- Rule: Hide auxiliary classes
Hide auxiliary/helper classes (i.e., classes private to a single compilation unit, not declared in a header) in functions, or in an anonymous namespace. Instead of:
struct Helper { ... }; void doit() { Helper h; ... }
write:
namespace { struct Helper { ... }; } void doit() { Helper h; ... }
or
void doit() { struct Helper { ... } h; ... }
The risk otherwise is to declare two classes with the same name: the linker will ignore one of the two silently. The resulting bugs are often difficult to understand.