据我所知,编译时类C字符串只作为一个实例保存在静态内存中。例如,我在下面的gcc 4.6运行示例中得到了true
。但我想知道它总是真的可以携带。 C和C ++上的行为很有趣。
#include <iostream>
bool amIportable(const char* value) {
const char* slocal = "Hello";
return (slocal==value);
}
int main() {
const char* s = "Hello";
std::cout << std::boolalpha
<< amIportable(s) << '\n'
<< amIportable("Hello") << '\n';
}
答案 0 :(得分:12)
不,这并非总是如此,也不是便携式的。
合并相同的字符串文字是由编译器和链接器协同执行的优化。 GCC和Microsoft编译器的最新版本都支持它,但只有在设置某些优化开关时才会支持它。
而且它不仅仅是一个“开启”或“关闭”功能。不同的编译器和不同的优化设置也会影响积极地执行此操作的方式。例如,有时字符串文字仅在单个函数的范围内合并,有时则在翻译单元的级别上发生,有时链接器可能会涉及跨多个翻译单元进行合并。
这是允许的,因为C和C ++标准将此行为保留为依赖于实现。
答案 1 :(得分:9)
不,它的实现依赖于C和C ++。
C11§6.4.5/ 7 字符串文字
如果这些数组的元素具有适当的值,则未指定这些数组是否相同。如果程序试图修改这样的数组,则行为是未定义的。
C ++11§2.14.5/ 12 字符串文字
是否所有字符串文字都是不同的(即存储在非重叠对象中)是实现定义的。尝试修改字符串文字的效果未定义。
答案 2 :(得分:2)
但我不知道它总是如此
不,至少C标准说的是“两个相同的字符串文字是否存储在同一个数组中是实现定义的”。
答案 3 :(得分:2)
您正在比较两种不同的字符串文字 具有相同的价值。根据C ++标准,它是 实现定义了相同的字符串文字是否占用 相同的内存与否(这意味着实现必须 记录它的作用);根据C标准,它是 不确定的。 (我认为C ++标准允许 实现以记录&#34;字符串的内容 如果相同内容的文字共享相同的实例 是在相同的翻译单位,并不共享相同 否则。)
如果你的目标是能够只比较指针,通常 解决方案是使用一个函数(静态,如果它是一个类成员) 返回字符串文字:
char const*
value()
{
return "Hello";
}
bool
isHello( char const* str )
{
return str == valule;
}
然后确保通过获取字符串的所有实例
致电value()
。