Names in C++ libraries
Any library will have various code entities that will be exposed to clients. Those entities will have names that the clients will use to refer to them. When a client makes uses of several different libraries, it is important that those libraries don’t make use of the same names as the others. Name collisions can be a big nuissance.
In order to prevent name collisions, each library should pick its own set of names in a way that they don’t happen to be used by other libraries as well. There are a few rules that can be followed by a library writer in order to ensure this.
First, let us introduce the notion of name set. A name set is a set of names
that can uniquely identify entities. The C++
namespace keyword defines name
namespace foo is the name set that contains all names qualified with
foo::. That is effectively a formal way to define name sets, but there are
other, informal, ways of defining name sets. In C, for example, there is a
tradition of using name prefixes to emulate namespaces: one can say that all
functions whose names start with
foo_ belong to library
foo. This tradition
is useful in C++ too because C++ namespaces cannot encompass all the entities in
the language we might want; macros are the usual suspect, and their names are
always in the global namespace.
In short, a name set can be defined as a C++ namespace, or it can be defined with a predicate that describes which names are part of it. Usually such predicates are not more complicated than just sharing a common prefix.
It is by sticking to well-defined name sets that a library can avoid name collisions when used alongside other libraries. These name sets must be as unique as possible. They must also be small enough that they don’t take names other libraries might want, and they must be large enough that the library has enough names to choose from. This is easily achieved by reserving a whole namespace for non-macro entities, and a specific prefix for macros.
Each library has absolute control over exactly two top-level name sets. One is used for macros, the other for non-macro entities. These name sets should be named after the library itself, which hopefully has a unique enough name. Within these name sets a library can use any name in any way it sees fit.
Example: In libfoo, all the macros start with
FOO_and all non-macro entities live within
Libraries should not take names from the global namespace. The only names from the global namespace that a library can take are the names in its macro name set and the name of the root namespace for non-macros.
Example: In libfoo, nothing is in the global namespace except for the macros
FOO_QUX, and for