When running the following C++ code in Xcode:
std::wstring str1 = L"1111";
std::wstring str2 = str1;
void* ptr1 = (void*)str1.c_str();
void* ptr2 = (void*)str2.c_str();
Result is that both pointers are equal. Is this by standard? In Visual Studio it's not the case.
It looks like the implementation is using the copy-on-write (COW) optimization, in which a strings internal state is only really set when a write operation is performed*. This was allowed in pre-C++11 implementations, but I don't think this is standard since C++11.
Note that you can check that the address of the underlying pointer changes when you access the string in a non-const manner, even without writing to it:
str2[0];
The evaluation of this expression should trigger a write operation which would change the address of the pointer. Here is a working example:
#include <string>
#include <iostream>
int main()
{
std::wstring str1 = L"1111";
std::wstring str2 = str1;
std::cout << (void*)str1.c_str() << " " << (void*)str2.c_str() << std::endl;
str2[0]; // forces a write operation. c_str() changes.
std::cout << (void*)str1.c_str() << " " << (void*)str2.c_str() << std::endl;
}
On a recent gcc, this yields
0x8a8e014 0x8a8e014
0x8a8e014 0x8a8e03c
* Some non-const accesses can trigger a write even if they don't semantically mutate the string, as shown in the example above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With