>我有这种情况:
// 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
。