14

据我所知,编译时类似 C 的字符串仅作为一个实例保存在静态内存中。例如,我true在下面的 gcc 4.6 运行示例中得到了两者。但我想知道它是否总是真实的并且可以携带。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';
}
4

4 回答 4

12

不,这并不总是正确的,也不是便携式的。

合并相同的字符串文字是由编译器和链接器共同执行的优化。GCC 和 Microsoft 的编译器的最新版本都支持它,但仅在设置了某些优化开关时才支持。

它不仅仅是一个“开”或“关”的功能。不同的编译器和不同的优化设置也会影响执行的积极程度。例如,有时字符串文字仅在单个函数的范围内汇集,有时它发生在翻译单元的级别,还有其他时候链接器可能会参与跨多个翻译单元的操作。

这是允许的,因为 C 和 C++ 标准将此行为视为依赖于实现。

于 2013-07-28T14:54:28.943 回答
9

不,它依赖于 C 和 C++ 的实现。

C11 §6.4.5/7字符串文字

如果它们的元素具有适当的值,则未指定这些数组是否不同。如果程序尝试修改这样的数组,则行为未定义。

C++11 §2.14.5/12字符串文字

是否所有字符串文字都是不同的(即,存储在不重叠的对象中)是实现定义的。尝试修改字符串文字的效果是未定义的。

于 2013-07-28T14:53:28.030 回答
2

但我想知道这是否总是正确的

不,至少 C 标准说“两个相同的字符串文字是否存储在同一个数组中是实现定义的”。

于 2013-07-28T14:54:49.730 回答
2

您正在比较两个不同的字符串文字,它们恰好具有相同的值。根据 C++ 标准,相同的字符串文字是否占用相同的内存是由实现定义的(这意味着实现必须记录它的作用);根据 C 标准,它是未指定的。(我假设 C++ 标准将允许实现按照“相同内容的字符串文字如果它们在同一个翻译单元中共享相同的实例,否则不共享相同的实例。)

如果您的目标是能够只比较指针,通常的解决方案是使用返回字符串文字的函数(如果它是类成员,则为静态):

char const*
value()
{
    return "Hello";
}

bool
isHello( char const* str )
{
    return str == valule;
}

然后确保通过调用获取字符串的所有实例value()

于 2013-07-28T15:30:28.020 回答