因此,我知道在C ++中,常量默认情况下与变量的链接不同。这就是为什么我不能放
int foo;
在某些标头中-链接器会正确地抱怨多个定义。太太,我会写
const int bar = 42;
在标头中,编译器确保只有一个定义bar
。
使用整数常量,很容易看出编译器是如何处理它的-至少只要没有人接受地址bar
或做一些其他有趣的事情(要求它为其分配存储空间)即可。但是,如果有人这样做怎么办?如果它不是一个完整的东西,而是需要在运行时执行代码的东西怎么办?假设我将其放入标题中:
const std::string baz = "h2g2";
假设没有小的字符串优化,那么这需要在运行时分配动态内存,因此需要执行代码,地址需要存储在某个地方,等等。
我以为baz
每个翻译单元都会有一个定义,只是编译器为其分配了内部链接以防止链接器抱怨?还是我错过了什么?
注意:我对constexpr
普通的C ++常量不感兴趣,因为它们自80年代就已存在,并且已在C ++ 98中进行了编码。(但是,如果全面的答案包括所有这些如何与融为一体constexpr
,我不会对此表示抱怨。)
像const
在C ++中那样声明一个对象(在名称空间范围),默认情况下为其分配内部链接。
如果声明(并由于初始化而定义)
const std::string baz = "h2g2";
在标题中,每个翻译单元都有一个静态链接的字符串。该地址必须存储在每个转换单元中(每个不同的非堆存储char文字有不同的地址-只读存储器)
编辑:正如C ++ 11题外话constexpr
所暗示的那样,const
因为它的意思是“适合于常量表达式求值”,因此它也应该具有内部链接。[Nb。我没有提到C ++ 14]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句