This question already has answers here:
Addresses of two char pointers to different string literals are same

(10个回答)


4年前关闭。




我想问一下,依赖跨翻译单元的字符串文字地址是否可移植? IE:

给定的文件 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 draft standard 告诉我们未指定相同的字符串文字是否不同,来自 6.4.5 字符串文字部分:



对于 C++,这在标准草案部分 2.14.5 字符串文字中包括:



允许编译器池字符串文字,但您必须了解它如何从编译器到编译器工作,因此这将不可移植并且可能会改变。 Visual Studio 包括一个 option for string literal pooling



请注意,在某些情况下,它确实符合条件。
gcc 确实支持池化和跨编译单元,您可以通过 -fmerge-constants 启用它:



注意,使用尝试和如果...支持它。

至于至少 C 不要求合并字符串文字的理由,我们可以从这个 archived comp.std.c discussion on string literals 中看出,理由是由于当时实现的种类繁多:

关于c++ - 跨翻译单元的字符串文字地址,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26279628/

10-12 14:58