Scottie T Scottie T -4 years ago 79
C++ Question

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:

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?

Answer Source

(In the following, the striked-through things are stuff that does not apply anymore to C++11, but did apply to C++03. C++11 makes almost no differences anymore (if there are, they are just language lawyer differences which I can't recall).).

Unnamed namespaces are a utility to make an identifier effectively translation unit local. They behave as if you would choose an 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 free functions called (for example) help that can exist in multiple translation units, and they won't clash at link time, since they all got an unique name due to their unique namespace they are in. The effect is almost identical to using the static keyword used in C which you can put in in the declaration of identifiers. static used in that manner is deprecated in C++, since unnamed namespaces are a superior alternative, being able to even make a type translation unit local.

namespace { int a1; }
static int a2;

Both a's are translation unit local and won't clash at link time. But the difference is that the a1 in the anonymous namespace just gets an unique name. It has still external linkage and may be exported into the symbol table of the object file being created. This becomes important if you want to use its address as a template argument:

template<int * ptr> struct sample { };

// OK - a1 has external linkage
sample<&a1> s1; 
// NOT OK - translation unit locality is done by giving a2 internal linkage. 
sample<&a2> s2; 

Template parameters has to have external linkage so in this case the identifier has to be put into an anonymous namespace.

Read the excellent article at comeau-computing `Why is an unnamed namespace used instead of static?.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download