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?