Uses for Anonymous Namespaces in Header Files

Uses for anonymous namespaces in header files

The only situation in which a nameless namespace in header can be useful is when you want to distribute code as header files only. For example, a large standalone subset of Boost is purely headers.

The token ignore for tuples, mentioned in another answer is one example, the _1, _2 etc. bind placeholders are others.

What if I need anonymous namespace in a header?

Stick with your Private namespace (or use the more popular detail). Remember the main idea behind C++ access mechanisms is make it difficult to misuse them, not impossible. Protect yourself against accidents, not malicious attacks.

Are static or unnamed namespace still useful when header and implementation are separated?

Keeping a definition in implementation file does not make it private in any sense. Any other header or implementation file can declare that function and use it. It's not always a bad thing - I used parts of private implementations of libraries when I really needed it (but I do not recommend doing that).

The worse part of having such not-so-private implementation is its potential for One Definition Rule violation. ODR states that every* function or variable must have exactly one definition in the whole program. If there is more than one definition, behaviour is undefined**.

This means that when you have your not-so-private implementation in your file and nobody knows about it, they can unknowingly write a function with the same name and arguments and get an ODR violation.

It would be a good practice to use static or anonymous namespace for all free functions that should be limited to a single file. Functions that need to be used from other files cannot use this strategy, so to limit the risk of ODR violations you should use descriptive names and perhaps (named) namespaces. Just make sure you don't overuse namespaces.


Note: using anonymous namespaces doesn't make sense in header files. Anonymous namespace limits the scope of its content to the translation unit in which it exists, but header files are copied and pasted into (potentially) multiple TUs. The one use of anonymous namespaces is in header-only libraries, as described in this question - it allows to create global objects in header file without ODR violation (but at a cost that each TU has its own copy of that variable).


*except for template functions, inline functions, functions defined in class definition and a couple more. Even then, all definitions must be exactly the same.

**When I encountered it once, linker used random definition, whichever it saw at that moment. Hilarity and long debugging sessions ensued.

Alternative for anonymous namespaces in header-only libraries

C++ doesn't have any mechanism to make entities in header files completely invisible to users. They can be made inaccessible if you want. This is normally achieved by member access control. You have to make foo_impl a private (possibly static) member of some class. Overloads of foo would then be either members or friends of the same class.

Alternatively, if you make foo_impl a member of a namespace named detail or foo_private or some such, users will normally understand they should not call this function. This works well in practice. Users will still be able to access the function at their own risk, but they will understand the risk. This should be plenty enough, as C++ doesn't protect you from malicious users anyway.

How would use of unnamed namespaces in headers cause ODR-violations?

The reason is that if you actually use anything in the anonymous
namespace, you risk undefined behavior. For example:

namespace {
double const pi = 3.14159;
}

inline double twoPiR( double r ) { return 2.0 * pi * r; }

The rule for inline functions (and classes, and templates, and
anything else which must be defined in multiple translation
units) is that the tokens must be identical (normally the case,
unless you hit some macro), and that all symbols must bind
identically. In this case, each translation unit has a separate
instance of pi, so the pi in twoPiR binds to a different
entity in each translation unit. (There are a few exceptions,
but they all involve integral expressions.)

Of course, even without the anonymous namespace, this would be
undefined behavior here (since const means internal linkage by
default), but the basic principle holds. Any use in a header of
anything in an unnamed namespace (or any const object defined in
the header) is likely to cause undefined behavior. Whether it
is a real problem or not depends, but certainly anything which
really involves the address of pi, above, is going to cause
problems. (I say "really" here, because there are many cases
where the address or a reference is formally used, but in
practice, the inline expansion will result in the value actually
being used. And of course, the token 3.14159 is 3.14159
regardless of where it appears.)

Uses of unnamed namespace in C++

According to Stroustrup, you should use it in places where in old C you would have made static globals. The idea is that the items in question can be "global" to the source file they are in, but not pollute the namespace of any other source files in your compilation.

In other words, you shouldn't be creating static globals in C++. You should be using unnamed namespaces instead.

I have found some situations where they are useful in header files, but that should be rare. Mostly I think for declaring throwable exceptions. In that case the definitions in question will be global for everything that #includes that header, but not for things that don't.

Why are unnamed namespaces used and what are their benefits?

Unnamed namespaces are a utility to make an identifier translation unit local. They behave as if you would choose 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 free functions called (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 in the declaration of identifiers. 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 gets a unique name.

Read the excellent article at comeau-computing Why is an unnamed namespace used instead of static? (Archive.org mirror).

(Anonymous) Namespaces, Functions, and Header Files

Move the unnamed namespace out of the other namespace:

namespace{
RNG rando = new RNG();
}

void Foo::SomeFunc(){
//implementation
}

void Foo::SomeOtherFunc(int){
//implementation
}

It can't be accessed outside the translation unit anyways.



Related Topics



Leave a reply



Submit