类使用全局外部常量变量,该变量通过内部链接定义
class using global extern const variable which is defined with internal linkage
>我有这种情况:
// 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
。
相关文章:
- 内联函数中具有内部链接的全局变量
- C++ SSE 内部函数:将结果存储在变量中
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 是否可以禁止在for循环体内部修改循环变量
- 当使用lambda进行变量的复杂初始化时,如何处理从内部抛出的lambda外部异常
- 在变量名后声明带有 () 的非内部类型与不使用变量名的行为不同。即 std::map<int,char>x(); - 这是怎么回事?
- 使用虚拟变量对 std::vector 内部循环进行切片的最佳方法
- 访问lambda内部循环控制变量
- 如何通过从变量中获取类型来访问内部 typedef
- 解决具有嵌套模板化变量的 Visual Studio 内部编译器错误
- 内部循环的变量
- lambda内部捕获的constexpr变量失去了其constexpr-ness
- 循环时内部的C 声明和初始化变量
- 用名称为“ this”内部括号内的变量在3个不同的编译器上导致不同的结果
- 使用动态铸件来返回派生类内部的变量的不同值
- 如何在 for 循环内部或外部打印双精度变量
- 当在函数内部使用静态变量时,输出会发生变化,该函数在c++中返回引用
- 函数内部静态变量的内存分配
- 在外部功能中具有一个变量初始化或内部功能中的多个初始化是最有效的
- 将更改此静态变量内部的函数的结果分配给静态变量