`const char*` 的断言保证是真的吗?

Is this assertion of `const char*` guaranteed to be true?

下面是代码示例(在 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;
}  

据我所知,字符串文字存储在地址 space 的 readonly 段中,而 const char*p = "ohoh"; 只是生成一个指向 position.However 的指针,似乎编译器只会生成该字符串文字的一个副本,因此 p==p1 为真。

是优化还是标准保证的?

不,标准不保证。根据cppref:

The compiler is allowed, but not required, to combine storage for equal or overlapping string literals. That means that identical string literals may or may not compare equal when compared by pointer.

该行为未指定,您不能依赖它。从标准来看,[lex.string]/16

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified.

对于p3p4,它们是不同的东西。请注意 pp1 是指针(指向字符串文字),但 p3p4 是从 string literals.

初始化的数组

String literals can be used to initialize character arrays. If an array is initialized like char str[] = "foo";, str will contain a copy of the string "foo".

也就是说p3p4是独立的数组。当衰减到指针时,它们会有所不同(因为它们指向不同的数组),然后 p3 == p4 将是 false.

编译器是否将相等的字符串文字存储为一个字符串文字由实现定义。所以这个比较

p == p1

可以生成 truefalse,具体取决于编译器选项。

至于数组,则它们没有 built-in 比较运算符。

而不是

assert(p == p1);
assert(p3 == p4);

你可以写

assert( strcmp( p, p1 ) == 0 );
assert( strcmp( p3, p4 ) == 0 );

字符串文字可能共享存储,并且可能在read-only内存中。

但两者都不能保证。

可以保证两个不同的数组不会共享 space,除非它们的生命周期不重叠。在后一种情况下,无论如何都没有一致的方法来证明它,所以谁在乎呢?