mardi 16 août 2016

Unexplained discrepancies when copying and modifying std::strings

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) = 'Z';

      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) = 'Z';

      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: 123Z5678
1. x1: 12345678
1. ptrs are equal
2. x0: 123Z5678
2. x1: 123Z5678
2. ptrs are equal

MSVC (2015)

1. x0: 123Z5678
1. x1: 12345678
1. ptrs are equal
2. x0: 123Z5678
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?

Aucun commentaire:

Enregistrer un commentaire