简体   繁体   中英

extern in namespace scope - gcc vs clang vs msvc

I've tested the seemingly strange code example below with the newest gcc , clang , and MSVC ; both clang and gcc give link errors, but MSVC compiles and links without any problem. Which one is correct?

// foo.h
#pragma once

namespace A
{
    class foo
    {
    public:
        foo();
        void print();
    };
}

// foo.cpp
#include <iostream>
#include "foo.h"

int* p = nullptr;

using namespace A;

foo::foo()
{
    p = new int(5);
}

void foo::print()
{
    extern int* p;
    std::cout << *p;
}

#include "foo.h"

int main()
{
    A::foo f;
    f.print();
}

gcc and clang:

foo.cpp:(.text+0x35): undefined reference to 'A::p'

Both GCC and Clang are standard compliant. The example and explanation are given in the standard [basic.namespace]/4 :

The enclosing namespaces of a declaration are those namespaces in which the declaration lexically appears, except for a redeclaration of a namespace member outside its original namespace (eg, a definition as specified in [namespace.memdef]). Such a redeclaration has the same enclosing namespaces as the original declaration. [ Example:

namespace Q {
  namespace V {
    void f();                   // enclosing namespaces are the global namespace, Q, and Q​::​V
    class C { void m(); };
  }
  void V::f() {                 // enclosing namespaces are the global namespace, Q, and Q​::​V
    extern void h();            // ... so this declares Q​::​V​::​h
  }
  void V::C::m() {              // enclosing namespaces are the global namespace, Q, and Q​::​V
  }
}

— end example]

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM