命名空间范围内的外部 - GCC vs clang vs msvc

extern in namespace scope - gcc vs clang vs msvc

本文关键字:vs clang msvc GCC 范围内 外部 命名空间      更新时间:2023-10-16

我已经用最新的gccclangMSVC测试了下面看似奇怪的代码示例;clang和gcc都会给出链接错误,但MSVC编译和链接没有任何问题。哪一个是正确的?

// 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 和 clang

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

GCC 和 Clang 都符合标准。示例和解释在标准 [basic.namespace]/4 中给出:

声明

的封闭命名空间是声明在词法上出现的那些命名空间,除了在其原始命名空间之外重新声明命名空间成员(例如,[namespace.memdef] 中指定的定义(。此类重新声明具有与原始声明相同的封闭命名空间。 [ 示例:

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
}
}

— 结束示例]