16

Is there a functional difference between these two nested usages of unnamed namespaces:

namespace A { namespace {
  void foo() {/*...*/}
}}

and

namespace { namespace A {
  void foo() {/*...*/}
}}

As far as I see it, both foos will get an internal unique identifier per compilation unit and can be accessed with A::foo - but is there a subtle or not-so-subtle difference that I'm not seeing?

Pietro
  • 12,086
  • 26
  • 100
  • 193
ltjax
  • 15,837
  • 3
  • 39
  • 62
  • 1
    (edited) You can effectively hide the second `foo` by declaring another `A::foo` at the file level. The first `foo` will be always accessible as `::A::foo`. Unless you reopen `A` and declare another `foo` there. That is, yes, pretty much the same. – n. m. could be an AI Jun 15 '11 at 13:55

1 Answers1

8

Exactly as you typed, there is no difference.

You can, of course, add declarations in the first level of namespace to booth examples and then it will be a difference.

namespace A {
  int i;         // Accessed globally in this file as "A::i".
  namespace {
    void foo() {/*...*/}
}}


namespace {
  int i;         // Accessed globally in this file simply as "i".
  namespace A {
    void foo() {/*...*/}
}}}

Note that, although you programmer have no way to distinguish, for the compiler, the namespaces are distinct:

unnamed_namespaces.cpp:42:5: error: reference to ‘A’ is ambiguous
unnamed_namespaces.cpp:19:17: error: candidates are: namespace A { }
unnamed_namespaces.cpp:28:19: error:                 namespace <unnamed>::A { }

Usefull:


EDIT:

In respect to ADL (Argument-dependent name lookup), I understand that it will be no precedence difference in overload resolution for other foo() as below:

#include    <iostream>

void foo() { std::cout << "::foo()" << std::endl; }

namespace A {
    namespace {
        void foo() { std::cout << "A::<unnamed>::foo()" << std::endl; }

        class   AClass
        {
        public:
            AClass( )
            {   foo( ); }
        };
    }
}


namespace {
    namespace B {
        void foo() { std::cout << "B::<unnamed>::foo()" << std::endl; }

        using namespace A;

        class   BClass
        {
        public:
            BClass( )
            {   foo( ); }

            ~BClass( )
            {   A::foo( );  }
        };
    }
}

int main( )
{
    A::foo( );
    B::foo( );
    foo( );

    A::AClass   a;
    B::BClass   b;

    return  0;
}

Compiler will prefer the closest foo( ) unless explicitly specified. So BClass constructor calls B::foo( ) even having a using namespace A on it. To call A::foo( ) on BClass destructor, the call must be explicitly qualified.

A::<unnamed>::foo()
B::<unnamed>::foo()
::foo()
A::<unnamed>::foo()
B::<unnamed>::foo()
A::<unnamed>::foo()

Maybe it become clearer if we think in nested named namespaces and how the argument-dependent will be solved. The olny difference will be an implicit using on the unnamed ones, but it won't change the compiler preference.

Community
  • 1
  • 1
j4x
  • 3,595
  • 3
  • 33
  • 64
  • 2
    I think your access example is backwards. The first one is `A::i` and the second is just `i`. – Dennis Zickefoose Jun 15 '11 at 21:06
  • While this is a superb answer so far, I was wondering what kinds of effects the namespaces can have on ADL - will `namespace A {void bar();}` be able able to find `foo ()` in any of the examples? – ltjax Jun 17 '11 at 09:46