复制和修改std :: strings时出现无法解释的差异

Jac*_*ohn 8 c++ string copy-constructor c++11

在下面的代码中,"情境1" 在所有测试的编译器上按预期工作,但"情况2"似乎根据所使用的编译器而表现不同.

作为示例,MSVC使sit1和sit2产生相同的结果,但是当使用gcc/clang和libstdc ++时,修改发生在原始字符串和它的副本(有点像COW字符串),即使我正在使用C +构建+11开关.

#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;
}
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会(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
Run Code Online (Sandbox Code Playgroud)

MSVC(2015)

1. x0: 123 5678
1. x1: 12345678
1. ptrs are equal
2. x0: 123 5678
2. x1: 12345678
2. ptrs are equal
Run Code Online (Sandbox Code Playgroud)

各种编译器之间的行为差​​异是否有任何原因 - 假设&x0 [0]和.data()返回相同的地址?

M.M*_*M.M 15

情境2导致未定义的行为:

char* ptr = const_cast<char*>(x0.data() + 3);

(*ptr) = 'Z';
Run Code Online (Sandbox Code Playgroud)

根据std::basic_string::data(C++ 14 [string.accessors]/3)的规范:

要求:程序不得更改存储在字符数组中的任何值.

换句话说,您const不能通过data()或返回的指针抛弃并修改字符串c_str().