以下是代码示例(在vs2015中编译并运行):
#include<cassert>
using namespace std;
int main() {
const char*p = "ohoh";
const char*p1 = "ohoh";
char p3[] = "ohoh";
char p4[] = "ohoh";
assert(p == p1);//OK,success,is this always true?
assert(p3 == p4);//failed
return 0;
}
据我所知,字符串文字存储在地址空间的readonly
段中,const char*p = "ohoh";
只生成指向该位置的指针。但是,编译器似乎只会生成该字符串文字的一个副本,因此p==p1
为真。
是优化还是标准保证的东西?
答案 0 :(得分:7)
不,标准不保证。根据{{3}}:
允许编译器(但不是必需的)将存储组合为相等或重叠的字符串文字。这意味着当通过指针进行比较时,相同的字符串文字可能会比较也可能不会相等。
答案 1 :(得分:7)
行为未指定,您不能依赖它。从标准[lex.string]/16
开始是否所有字符串文字都是不同的(即,存储在非重叠对象中)以及是否对字符串文字的连续评估产生相同或不同的对象是未指定的。
对于p3
和p4
,它们是不同的东西。请注意,p
和p1
是指针(指向字符串文字),但p3
和p4
是从string literals初始化的数组。
字符串文字可用于初始化字符数组。如果数组初始化为
char str[] = "foo";
,则str
将包含字符串"foo"
的副本。
这意味着p3
和p4
是独立的数组。当衰减到指针时它们会不同(因为它们指向不同的数组),那么p3 == p4
将是false
。
答案 2 :(得分:1)
实现定义了编译器是否将相等的字符串文字存储为一个字符串文字。所以这个比较
p == p1
可以产生true
或false
,具体取决于编译器选项。
对于数组,它们没有内置的比较运算符。
而不是
assert(p == p1);
assert(p3 == p4);
你可以写
assert( strcmp( p, p1 ) == 0 );
assert( strcmp( p3, p4 ) == 0 );
答案 3 :(得分:0)
字符串文字可能共享存储空间,而可能位于只读存储器中。
但两者都没有保证。
保证两个不同的阵列不会共享空间,除非它们的生命周期不重叠。在后一种情况下,无论如何都没有合适的方式证明它,所以谁在乎呢?