静态内存实例中的字符串计数

据我所知,编译时类C字符串只作为一个实例保存在静态内存中。 例如,我在下面的gcc 4.6运行示例中得到了同样的结果。 但我想知道它总是真的可以携带。 C和C ++上的行为很有趣。

 #include  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'; } 

不,这并非总是如此,也不是便携式的。

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

而且它不仅仅是一个“开启”或“关闭”function。 不同的编译器和不同的优化设置也会影响其执行的积极程度。 例如,有时字符串文字仅在单个函数的范围内合并,有时在翻译单元的级别上发生,有时链接器可能涉及跨多个翻译单元进行合并。

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

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

C11§6.4.5/ 7 字符串文字

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

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

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

但我想知道它总是如此

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

您正在比较两个不同的字符串文字,它们碰巧具有相同的值。 根据C ++标准,实现定义了相同的字符串文字是否占用相同的内存(这意味着实现必须记录它的作用); 根据C标准,它没有具体说明。 (我认为C ++标准允许实现记录某些内容,如果相同内容的字符串文字在同一个翻译单元中共享同一个实例,否则不共享相同的实例。)

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

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

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