Consider this fragment of C++ code:
namespace
{
void f()
{
}
class A
{
void f()
{
::f(); // VC++: error C2039: 'f' : is not a member of '`global namespace''
}
};
}
GCC compiles this just fine. Visual C++ 2008 fails to compile spitting out the C2039 error. Which one of these two compilers is correct here? Is there any way to reference that "global" f
properly?
Edit: Zack suggested to try and it works with both compilers. Looks a bit weird to me.
namespace
{
void f()
{
}
class A
{
void f();
};
}
void A::f()
{
::f();
}
An anonymous namespace makes the enclosed variables, functions, classes, etc. available only inside that file. In your example it's a way to avoid global variables. There is no runtime or compile time performance difference.
November 19, 2020. Anonymous namespaces in C++ allow you to define locally-visible-only artifacts in C++. the static keyword provides equivalent (depending on C++ version) locally-visible-only variables and functions. //impl.cpp. //neither can be used externally.
Inline namespaces are a library versioning feature akin to symbol versioning, but implemented purely at the C++11 level (ie. cross-platform) instead of being a feature of a specific binary executable format (ie. platform-specific).
Beginning of C++ only. Global scope or global namespace scope is the outermost namespace scope of a program, in which objects, functions, types and templates can be defined. A name has global namespace scope if the identifier's declaration appears outside of all blocks, namespaces, and classes.
VC++ 2008 is wrong here. According to the c++03 standard 3.4.3.4:
A name prefixed by the unary scope operator :: (5.1) is looked up in global scope, in the translation unit where it is used. The name shall be declared in global namespace scope or shall be a name whose declaration is visible in global scope because of a using-directive (3.4.3.2). The use of :: allows a global name to be referred to even if its identifier has been hidden (3.3.7).
The important part here is that a using directive in the global namespace will make those symbols accessible with the scope operator.
And according to 7.3.1.1/1, an anonymous namespace is equivalent to:
namespace *unique* { /* empty body */ }
using namespace *unique*;
namespace *unique* { namespace-body }
So between these two sections, the standalone function should be accessible in global namespace.
As academicRobot points out, Visual C++ is wrong. As a workaround, adding an empty unnamed namespace block should resolve the issue (I don't have Visual C++ 2008 to test, but this works in Visual C++ 2010):
// empty unnamed namespace to placate compiler
namespace { }
namespace {
void f() { }
struct A {
void f() { ::f(); }
};
}
I've reported the issue to the Visual C++ team.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With