我遇到这种情况:
// 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中的两行?
答案 0 :(得分:0)
关于const定义的内部联系的假设并不总是正确的。请参见标准部分3.5 Program linkage
,p。 3(我引用的是N3690):
具有命名空间范围(3.3.6)的名称具有内部链接(如果它是
的名称)
显式声明为static的变量,函数或函数模板;或者,
显式声明为const或constexpr的非易失性变量,既未明确声明为extern,也未声明先前已声明具有外部链接;或
匿名工会的数据成员。
因此,对于第一种情况,param
具有外部链接,一切正常。
对于第二种情况,core.cpp中有一个内部链接的param
,但是还有另一个声明的param
具有外部链接但没有定义。
在第三种情况下,再次有一个param
。