Search code examples
c++oopnamespacesunnamed-namespace

Why are unnamed namespaces used and what are their benefits?


I just joined a new C++ software project and I'm trying to understand the design. The project makes frequent use of unnamed namespaces. For example, something like this may occur in a class definition file:

// newusertype.cc
namespace {
  const int SIZE_OF_ARRAY_X;
  const int SIZE_OF_ARRAY_Y;
  bool getState(userType*,otherUserType*);
}

newusertype::newusertype(...) {...

What are the design considerations that might cause one to use an unnamed namespace? What are the advantages and disadvantages?


Solution

  • Unnamed namespaces are a utility to make an identifier be translation unit-local. They behave as if you had chosen a unique name per translation unit for a namespace:

    namespace unique { /* empty */ }
    using namespace unique;
    namespace unique { /* namespace body. stuff in here */ }
    

    The extra step using the empty body is important, so you can already refer within the namespace body to identifiers like ::name that are defined in that namespace, since the using directive already took place.

    This means you can have two or more free functions named, for example,help that can exist in multiple translation units, and they won't clash at link time. The effect is almost identical to using the static keyword used in C which you can put in the declarations of identifiers. Unnamed namespaces are a great improvement over static as they even allow making types translation-unit-local.

    // perhaps declared in translation unit A
    namespace { int a; }
    // perhaps declared in translation unit B
    static int a;
    

    Both the declaration in the unnamed namespace and the static variable declaration are translation-unit-local, and thus won't clash at link time, but the difference is that the declaration in the unnamed namespace gets a unique name.

    You might consider reading the excellent article at comeau-computing: Why is an unnamed namespace used instead of static? (Archive.org mirror).