使用全局extern const变量的类,它使用内部链接定义

时间:2014-01-11 16:55:17

标签: c++ static global-variables const extern

我遇到这种情况:

// Test.h
extern const int param;
class Test
{
private:
    int i;
public:
    int foo();
};

// Test.cpp
#include "Test.h"
int Test::foo() { return param*10; }

// core.h
#include "Test.h"
const int param = 1; // should have internal linkage later in core.cpp
int do_stuff ();

// core.cpp
#include "core.h"
int do_stuff () { Test obj; return obj.foo(); }
int main() { return do_stuff(); }

但是没有链接器错误。链接器如何通过内部链接(默认为const定义)在core.cpp中定义的const int param查看Test.cpp中的// core.h const int param = 1; #include "Test.h" int do_stuff ();

当我像这样重写core.h时(更改两行):

param

缺少// core.h extern const int param = 1; #include "Test.h" int do_stuff (); 时出现链接器错误。然后,当我改变它时:

{{1}}

一切都有效。

我想,也许在最初的情况下,在core.cpp中有一个类Test的自动内联,因此Test.cpp不存在,整个代码都在core.cpp中,所以一切正常。但是为什么它应该依赖于更改core.h中的两行?

1 个答案:

答案 0 :(得分:0)

关于const定义的内部联系的假设并不总是正确的。请参见标准部分3.5 Program linkage,p。 3(我引用的是N3690):

  

具有命名空间范围(3.3.6)的名称具有内部链接(如果它是

的名称)      
    
        
  • 显式声明为static的变量,函数或函数模板;或者,

  •     
  • 显式声明为const或constexpr的非易失性变量,既未明确声明为extern,也未声明先前已声明具有外部链接;或

  •     
  • 匿名工会的数据成员。

  •     
  

因此,对于第一种情况,param具有外部链接,一切正常。

对于第二种情况,core.cpp中有一个内部链接的param,但是还有另一个声明的param具有外部链接但没有定义。

在第三种情况下,再次有一个param