views:

1248

answers:

4

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?

+6  A: 

Having something in an anonymous namespace means it's local to this translation unit (.cpp file and all it's includes) this means that if another symbol with the same name is defined elsewhere there will not be a violation of the One Definition Rule (ODR).

This is the same as the C way of having a static global variable or static function but it can be used for class definitions as well (and should be used rather than static in C++).

All anonymous namespaces in the same file are treated as the same namespace and all anonymous namcspaces in different files are distinct. An anonymous namespace is the equivalent of:

namespace __unique_compiler_generated_identifer0x42 {
    ...
}
using namespace __unique_compiler_generated_identifer0x42;
Motti
+1  A: 

An anonymous namespace makes the enclosed variables, functions, classes, etc. available only inside that file. In your example it's a way to avoid global variables. There is no runtime or compile time performance difference.

There isn't so much an advantage or disadvantage aside from "do I want this variable, function, class, etc. to be public or private?"

Max Lybbert
Anonymous namespaces should *not* be used in header files
Motti
Good point, edited.
Max Lybbert
+28  A: 

anonymous 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 anonymous 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?.

Johannes Schaub - litb
Good explanation!
ltcmelo
+1 for the link to `Why is an unnamed namespace used instead of static?`
Igor Oks
A: 

The example shows that the people in the project you joined don't understand anonymous namespaces :)

namespace {
    const int SIZE_OF_ARRAY_X;
    const int SIZE_OF_ARRAY_Y;

These don't need to be in an anonymous namespace, since const object already have static linkage and therefore can't possibly conflict with identifiers of the same name in another translation unit.

    bool getState(userType*,otherUserType*);
}

And this is actually a pessimisation: getState() has external linkage. It is usually better to prefer static linkage, as that doesn't pollute the symbol table. It is better to write

static bool getState(/*...*/);

here. I fell into the same trap (there's wording in the standard that suggest that file-statics are somehow deprecated in favour of anonymous namespaces), but working in a large C++ project like KDE, you get lots of people that turn your head the right way around again :)