字符串跨翻译单位的文字地址
String Literal address across translation units
我想问一下,在翻译单元之间依赖字符串文字地址是否可以移植?I.e:
给定的文件foo.c
引用了字符串文字"I'm a literal!"
,在其他给定的文件(例如bar.c
)中,相同的字符串文字"I'm a literal!"
将具有同一内存地址,这是否正确且可移植?考虑到每个文件都将被翻译成一个单独的.o
文件。
为了更好地说明,下面是一个示例代码:
# File foo.c
/* ... */
const char * x = "I'm a literal!"
# File bar.c
/* ... */
const char * y = "I'm a literal!"
# File test.c
/* ... */
extern const char * x;
extern const char * y;
assert (x == y); //Is this assertion going to fail?
还有一个gcc命令行示例:
gcc -c -o foo.o -Wall foo.c
gcc -c -o bar.o -Wall bar.c
gcc -c -o test.o -Wall test.c
gcc -o test foo.o bar.o test.o
在同一个翻译单元里呢?如果字符串文字在相同的翻译单元中,这是否可靠?
不能依赖具有相同内存位置的相同字符串文字,这是一个实现决策。C99标准草案告诉我们,未指定相同的字符串文字是否不同,从6.4.5
部分字符串文字:
未指定这些阵列是否是不同的,只要它们元素具有适当的值。如果程序尝试修改这样的数组,行为是未定义的。
对于C++,这在标准草案2.14.5
字符串文本中有介绍,其中写道:
是否所有字符串文字都是不同的(即,存储在非重叠对象)是实现定义的。尝试修改字符串文字是未定义的。
编译器可以池字符串文字,但您必须了解它在不同编译器之间的工作方式,因此这是不可移植的,可能会发生变化。Visual Studio包含一个字符串文字池选项
在某些情况下,可以合并相同的字符串文字以节省空间在可执行文件中。在字符串文字池中,编译器会导致对特定字符串文字的所有引用都指向同一个内存中的位置,而不是每个参考点都指向字符串文字的单独实例。要启用字符串池,请使用/GF编译器选项。
请注意,在某些情况下,它确实符合。
gcc
确实支持池化和跨编译单元,您可以通过-fmerge常量打开它:
尝试合并相同的常量(字符串常量和浮点常量)。
如果汇编程序并且链接器支持它。使用-fno merge常量可以禁止行为
注意,尝试和的使用如果。。。支持它。
至于C不需要合并字符串文字的基本原理,我们可以从这篇存档的comp.std.C关于字符串文字的讨论中看到,基本原理是由于当时实现的多样性:
海湾合作委员会可能是一个例子,但不是动机。部分原因是希望在可ROM数据中具有字符串文字是为了支持呃,ROMming。我隐约记得曾经使用过几个C实现(在做出X3J11决策之前)字符串文字是自动汇集或存储在恒定数据程序部分中。考虑到现有的各种实践和当需要原始的UNIX属性时最好不要试图保证字符串的唯一性和可写性文字。
否,不能期望相同的地址。如果它发生了,就会发生。但没有任何强制措施。
§2.14.5/12
是否所有字符串文字都是不同的(即,存储在非重叠对象)是实现定义的。尝试修改字符串文字是未定义的。
编译器可以随心所欲。如果它们位于不同的转换单元,或者即使它们位于同一转换单元,它们也可以存储在不同的地址中,而不管它们是只读存储器。
例如,在MSVC上,这两种情况下的地址完全不同,但同样:没有什么能阻止编译器合并指针的值(即使是中的,只要只读部分约束是强制性的)。
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 如何在c++程序中找到函数的地址
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 被解释为低级别const的const对象的地址
- 将地址分配给本地指针后,公共对象的变量将消失
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 内联程序集printf将整数解释为地址
- 为什么指针不写入类的地址?
- 如何在C++中获取该对象的类声明中对象的地址?
- 通过按地址访问变量
- c++中整数文字的内存地址c++中不允许使用指向整数文本的
- 字符串跨翻译单位的文字地址
- 检查相等的字符串文字是否存储在同一地址
- 是否有可能在文字地址处更改浮点数(值)
- 如何查找字符串文字的地址