在下面的代码中,“情况 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;
}
海湾合作委员会 (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
鉴于 &x0[0] 和 .data() 返回相同的地址,各种编译器之间的行为差异是否有任何原因?
最佳答案
情况 2 导致未定义的行为:
char* ptr = const_cast<char*>(x0.data() + 3);
(*ptr) = 'Z';
根据 std::basic_string::data
(C++14 [string.accessors]/3) 的规范:
Requires: The program shall not alter any of the values stored in the character array.
换句话说,您不能丢弃 const
并通过 data()
或 c_str()< 返回的指针修改字符串
.
关于c++ - 复制和修改 std::strings 时无法解释的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38985345/