提问人:sbi 提问时间:7/16/2014 最后编辑:Communitysbi 更新时间:7/16/2014 访问量:321
非整数常量在 C++ 中如何工作?[复制]
How do non-integral constants work in C++? [duplicate]
问:
所以我知道在 C++ 中,常量默认与变量的链接不同。这就是为什么我不能把
int foo;
在某些标题中 - 链接器将正确地抱怨多个定义。OTOH,我可以写
const int bar = 42;
,编译器确保只有一个定义。bar
使用积分常量,很容易看出编译器如何处理这个问题——至少只要没有人获取它的地址或做一些其他有趣的事情,要求它为它分配存储)。但是,如果有人这样做了怎么办?如果它不是一个整体,而是需要在运行时执行代码的东西呢?假设我把它放到一个标题中:bar
const std::string baz = "h2g2";
假设没有小的字符串优化,这需要在运行时分配动态内存,因此需要执行代码,需要将地址存储在某个地方,等等。
我假设我最终会得到每个翻译单元的一个定义,只是编译器为其分配了内部链接以防止链接器抱怨?还是我错过了什么?baz
注意:我对 constexpr
不感兴趣,只对普通的旧 C++ 常量感兴趣,因为它们自 80 年代以来就存在,并且是用 C++98 编纂的。(但是,如果一个全面的答案包括这一切如何与 constexpr
结合在一起,我不会抱怨这一点。
答:
4赞
Marco A.
7/16/2014
#1
默认情况下,像在 C++ 中那样声明对象(在命名空间范围内)会为其分配内部链接。const
如果声明(并因初始化而定义)
const std::string baz = "h2g2";
在标题中,每个翻译单元都有一个静态链接的字符串。地址必须存储在每个转换单元中(每个不同的非堆存储字符文本的不同地址 - 只读内存)
编辑:正如 C++11 题外话所暗示的那样,因为它的意思是“适用于常量表达式评估”,因此它也应该具有内部链接。[注意:我没有提到C++14]constexpr
const
评论
0赞
MSalters
7/16/2014
SSO(小字符串优化)适用于 的内容,而不是字符串文字。你的最后一句话似乎混淆了两者;SSO 无法影响文本baz
char[]
0赞
Marco A.
7/16/2014
@sbi在这种情况下,不应发生 SSO,因为数据是 char 文本,其地址在编译时是已知的
0赞
Marco A.
7/16/2014
谢谢ruben,如果有人没有看到你的评论,我会把它添加到答案中
2赞
R. Martinho Fernandes
7/16/2014
但是,请注意,“暗示”对于变量确实是正确的,即使在 C++14 中也是如此。constexpr
const
评论
bar
static