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?
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 .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.