类使用全局外部常量变量,该变量通过内部链接定义

class using global extern const variable which is defined with internal linkage

本文关键字:变量 内部 链接 定义 全局 外部 常量      更新时间:2023-10-16

>我有这种情况:

// 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(); }

但是,没有链接器错误。链接器如何查看 Test.cpp通过 core.h 在 core 中定义的const int param.cpp具有内部链接(常量定义的默认值)?

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

// core.h
const int param = 1;
#include "Test.h"
int do_stuff ();
缺少

param出现链接器错误。然后,当我像这样更改它时:

// core.h
extern const int param = 1;
#include "Test.h"
int do_stuff ();

一切再次奏效。

我想,也许在原始情况下,在 core.cpp 内部会自动内联类 Test,这样 Test.cpp 就不存在了,整个代码都在 core.cpp 中,这样一切都可以工作。但是,为什么它应该依赖于更改core.h中的两行呢?

你对常量定义的内部链接的假设并不总是正确的。请参阅标准部分3.5 Program linkage,第 3 页(我引用 N3690):

具有命名空间作用域 (3.3.6) 的名称具有内部链接,如果它是

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

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

  • 匿名工会的数据成员。

所以对于第一种情况,param有外部联系,一切都很好。

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

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