Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly reference a function in an anonymous namespace

Tags:

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();
}
like image 973
detunized Avatar asked Mar 31 '11 17:03

detunized


People also ask

What is the use of anonymous namespace in C++?

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.

What does anonymous namespace mean?

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.

What is an inline namespace?

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).

What is global namespace C++?

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.


2 Answers

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.

like image 163
academicRobot Avatar answered Oct 12 '22 01:10

academicRobot


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.

like image 24
James McNellis Avatar answered Oct 12 '22 01:10

James McNellis