Search code examples
c++c++11namespacesinline-namespaces

Wherefore inline unnamed namespaces?


A quick one for the gurus: C++11 allows unnamed namespaces to be declared inline. This seems redundant to me; things declared in an unnamed namespace are already used as if they were declared in the enclosing namespace.

So my question is this: what does it mean to say

inline namespace /*anonymous*/ {
    // stuff
}

and how is it different from the traditional

namespace /*anonymous*/ {
    // stuff
}

that we know and love from C++98? Can anyone give an example of different behaviour when inline is used?

EDIT: Just to clarify, since this question has been marked as a duplicate: I'm not asking about named inline namespaces in general. I understand the use-case there, and I think they're great. I'm specifically asking what it means to declare an unnamed namespace as inline. Since unnamed namespaces are necessarily always local to a TU, the symbol versioning rational doesn't seem to apply, so I'm curious about what adding inline actually does.


As an aside, the standard [7.3.1.1], regarding unnamed namespaces, says:

inline appears if and only if it appears in the unnamed-namespace-definition

but this seems like a tautology to my non-language lawyer eyes -- "it appears in the definition iff it appears in the definition"! For bonus points, can anyone explain what this bit of standardese is actually saying?

EDIT: Cubbi claimed the bonus point in the comments:

the standard is saying that unnamed-namespace-definition behaves as if it were replaced by X where inline appears in X iff it appears in the unnamed-namespace-definition


Solution

  • Here is one use that I have found:

    namespace widgets { inline namespace {
    
    void foo();
    
    } } // namespaces
    
    void widgets::foo()
    {
    }
    

    In this example, foo has internal linkage and we can define the function later on by using the namespace::function syntax to ensure that the function's signature is correct. If you were to not use the widgets namespace then the void foo() definition would define a totally different function. You also don't need to re-open the namespace saving you a level of indentation.

    If there is another function called foo in the widgets namespace already then this will give you an ambiguity instead rather than a nasty ODR violation.