这是关于内联变量及其在多个翻译单元中的唯一性的问题。请考虑以下代码,它们跨两个翻译单元共享一个字符串文字:
文件hdr.h:
inline const char* const str = "hello world";
文件tu0.cpp:
#include <cstdio>
#include "hdr.h"
void foo()
{
printf("tu0: &str=%p, str=%p\n", &str, str);
}
文件tu1.cpp:
#include <cstdio>
#include "hdr.h"
extern void foo();
int main()
{
foo();
printf("tu1: &str=%p str=%p\n", &str, str);
}
为了完整性,这是我编译这些的方法(在linux,64位,binutils 2.28上):
$ CXX -c -std=c++1z tu0.cpp -o tu0.o
$ CXX -c -std=c++1z tu1.cpp -o tu1.o
$ CXX -std=c++1z tu*.o -o a.out
使用CXX = clang-4.0,str和&amp; str都是相同的:
tu0: &str=0x400608 str=0x4005f9
tu1: &str=0x400608 str=0x4005f9
但是使用g ++版本7.1和7.2,我得到了令人惊讶的结果:
tu0: &str=0x4005d8 str=0x4005b4
tu1: &str=0x4005d8 str=0x4005e0
好的,我实际上有一个以上的问题(但它们都是相关的):
str和&amp; str在所有翻译单元中都应该具有相同的值吗?
N4687 [dcl.inline] / 6表示内联变量应该在每个翻译单元中具有相同的定义。是&#39;定义&#39;参考源令牌&#34; hello world&#34;或字符串文字的指针值&#34; hello world&#34;?
GCC如何设法为str获取相同的地址,但取决于访问变量的位置有不同的值?这导致了最后一个问题:
内联变量是否需要比单个翻译单元中手动定义的extern声明的常规方法更多的运行时开销(每次访问时)?