2

Here is the code example(compiled and run in 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;
}  

As far as I know,the string literals are stored in the readonly segment in address space,and const char*p = "ohoh"; just generate a pointer to that position.However,it seems like the compiler will just generate one copy of that string literal,so the p==p1 is true.

Is it a optimization ,or something guaranteed by the standard?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
choxsword
  • 3,187
  • 18
  • 44
  • 1
    The standard doesn't guarantee anything concerning `p` and `p1`, they might point to the same memory location or not. – Jabberwocky Apr 10 '18 at 11:23
  • It most likely isn't. There are optimization options for merging identical strings (String Pooling in VS), so that kind of implies compilers are not obligated to do it as per standard. – CookiePLMonster Apr 10 '18 at 11:23
  • Isn't it the case, that `p3` and `p4` are separate arrays, that are both initialized with the same string literal. – mschmidt Apr 10 '18 at 11:24
  • 1
    @mschmidt yes, but `p3` and `p4` are not mentioned in the question. – Jabberwocky Apr 10 '18 at 11:25
  • @Michael-Walz, sure, but I think the question stems from the confusion about `p` and `p1` vs the behaviour of `p3` and `p4`. I.e. arrays and pointers are not the same thing. – mschmidt Apr 10 '18 at 11:27
  • @CookiePLMonster There are both options to get the compiler to conform to the standard, as well as others to force it to diverge. They normally are mostly for back-compat or efficiency. – Deduplicator Apr 10 '18 at 11:33

4 Answers4

7

No, it is not guaranteed by the standard. According to 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.

Lingxi
  • 14,579
  • 2
  • 37
  • 93
7

The behavior is unspecified, you can't rely on it. From the standard, [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.

For p3 and p4, they're different things. Note that p and p1 are pointers (to string literal) but p3 and p4 are arrays initialized from 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".

That means p3 and p4 are independent arrays. When decay to pointer they'll be different (because they point to different arrays), then p3 == p4 would be false.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1

It is implementation defined whether equal string literals are stored by the compiler as one string literal. So this comparison

p == p1

can yield either true or false depending on the compiler options.

As for arrays then they do not have a built-in comparison operator.

Instead of

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

you could write

assert( strcmp( p, p1 ) == 0 );
assert( strcmp( p3, p4 ) == 0 );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    It is **not** implementation defined. It is unspecified. The difference is that when something is implementation defined, a conforming compiler is **required** to document what it does. – Pete Becker Apr 10 '18 at 12:18
  • @PeteBecker And it does document.:) See the description of the compiler options.:) – Vlad from Moscow Apr 10 '18 at 12:31
  • 1
    "Unspecified" does not mean "must not document". I neglected to mention that my comment is about the **definition** of those two **technical terms** in the C++ standard. – Pete Becker Apr 10 '18 at 12:33
0

String literals may share storage, and may be in read-only memory.

Neither is guaranteed though.

What is guaranteed is that two different arrays won't share space unless their lifetime does not overlap. In the latter case there's no conforming way to prove it anyway, so who cares?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118