Search code examples
c++namespacesc++17c++14name-lookup

variables declaration in anonymous namespace and definition in other place


Can someone explain why I can't define variable that was declared in anonymous namespace as global variable in another place?

#include <iostream>
namespace  {
    extern int number;
}

int number = 123;

void g() {
    std::cout << number;
}

Compiler says that "Reference to 'number' is ambiguous" but I can't understand why it recognises declaration and definition as different things? Thank you in advance.


Solution

  • For the unqualified name-lookup the compiler considers also nested unnamed namespaces in the global namespace,

    You declared two different objects with the same name in the global namespace and in the nested unnamed namespace.

    The using directive for unnamed namespace is implicitly inserted in the enclosing namespace.

    Consider the following demonstration program

    #include <iostream>
    
    namespace N
    {
        extern int number;
    }
    
    using namespace N;
    
    int number = 123;
    
    int main()
    {
        std::cout << number << '\n';
    }
    

    The compiler will issue an error due to the ambiguity for the unqualified reference to the name number in this statement

    std::cout << number << '\n';
    

    The similar situation takes place with an unnamed namespace because the using directive is implicitly inserted in the enclosing namespace.

    From the C++ 20 Standard (9.8.2 Namespace definition)

    7 Members of an inline namespace can be used in most respects as though they were members of the enclosing namespace. Specifically, the inline namespace and its enclosing namespace are both added to the set of associated namespaces used in argument-dependent lookup (6.5.3) whenever one of them is, and a using directive (9.8.4) that names the inline namespace is implicitly inserted into the enclosing namespace as for an unnamed namespace (9.8.2.2).