【问题标题】:extern in namespace scope - gcc vs clang vs msvc命名空间范围内的外部 - gcc vs clang vs msvc
【发布时间】:2020-10-12 11:32:32
【问题描述】:

我用最新的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'

【问题讨论】:

    标签: c++ visual-c++ namespaces language-lawyer extern


    【解决方案1】:

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

    —结束示例]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-29
      • 1970-01-01
      • 2018-07-29
      • 2017-08-21
      • 2014-04-04
      • 1970-01-01
      • 2011-08-12
      • 2014-11-02
      相关资源
      最近更新 更多