sebrockm
sebrockm

Reputation: 6012

Can a function be defined in global namespace if it is declared in an anonymous namespace?

In production code I found this in a .cpp file:

namespace
{
    void foo(); // declared in anonymous namespace, defined below
}

void bar() // declared in corresponding .h file, defined here
{
    ::foo(); // call foo
}

void ::foo() // intended to refer to the anonymous foo above
{
}

We are using Visual Studio 2017. I stumbled over this because intellisense gave me a warning for foo that it could not find the function definition. However, it compiles and links without errors and the code does what it is supposed to do.

I godbolted it and found that gcc and clang reject this code for the same reason that intellisense gave me a warning for.

So my question is: Which compiler is correct and why?


Furthermore, out of interest I added another declaration of foo to the global namespace, like so:

namespace
{
    void foo();
}

void foo(); // another declaration

void bar()
{
    ::foo(); // which foo will be called?
}

void ::foo() // which foo will be defined?
{
}

Now, gcc gives me an error:

error: explicit qualification in declaration of 'void foo()'

Clang compiles it, but gives me a warning:

warning: extra qualification on member 'foo' [-Wextra-qualification]

And msvc compiles it just fine.

Again, which compiler - if any - is correct here?

Upvotes: 5

Views: 630

Answers (1)

Fred Larson
Fred Larson

Reputation: 62113

Have a look at the cppreference page on unnamed namespaces:

This definition is treated as a definition of a namespace with unique name and a using-directive in the current scope that nominates this unnamed namespace.

So an "anonymous" namespace is not the global namespace, nor is it even unnamed. Rather, it has a compiler-provided unique name. So ::foo() is not the function in your anonymous namespace. MSVC is incorrect here.

And you can't define your anonymous namespace function outside its anonymous namespace.

Upvotes: 6

Related Questions