In the following code, "situation 1" works as expected on all compilers tested, however "situation 2" it seems to behave differently based on the compiler used.
As an example MSVC has sit1 and sit2 produce the same results, however when using gcc/clang and libstdc++, the modification occurs to the original string and it's copy (sort of like a COW string) even though I'm building using the C++11 switch.
#include <iostream>
#include <string>
int main() {
// situation 1
{
std::string x0 = "12345678";
std::string x1 = x0;
char* ptr = &x0[0] + 3;
(*ptr) = ' ';
std::cout << "1. x0: " << x0 << "\n";
std::cout << "1. x1: " << x1 << "\n";
if ((&x0[0]) == x0.data()) std::cout << "1. ptrs are equal\n";
}
// situation 2
{
std::string x0 = "12345678";
std::string x1 = x0;
char* ptr = const_cast<char*>(x0.data() + 3);
(*ptr) = ' ';
std::cout << "2. x0: " << x0 << "\n";
std::cout << "2. x1: " << x1 << "\n";
if ((&x0[0]) == x0.data()) std::cout << "2. ptrs are equal\n";
}
return 0;
}
GCC (6.1)
1. x0: 123 5678
1. x1: 12345678
1. ptrs are equal
2. x0: 123 5678
2. x1: 123 5678
2. ptrs are equal
MSVC (2015)
1. x0: 123 5678
1. x1: 12345678
1. ptrs are equal
2. x0: 123 5678
2. x1: 12345678
2. ptrs are equal
Is there any reason for the discrepancies in behavior between the various compilers - given that &x0[0] and .data() return the same address?
4
withZ
? Could you not find something that's even harder to distinguish visually, likel
andI
? Half the fun of asking questions on SO is making it as hard as possible for anyone to spot the important details. – Mcpeakstd::string
:-) – Mcpeakuintptr_t
and print them out, you will see thatx1.data()
andx1.data()
are different.ptr
is pointing to somewhere inx0
in situation 1 andx1
in situation 2. Definitely some interaction between UB and CoW. – Metachromatism