std::basic_string::data
has a requirement under its specification.
[string.accessors] (emphasis mine)
const charT* c_str() const noexcept; const charT* data() const noexcept;
1 Returns: A pointer
p
such thatp + i == &operator[](i)
for eachi
in[0, size()]
.2 Complexity: Constant time.
3 Requires: The program shall not alter any of the values stored in the character array.
This made sense in C++03 for c_str
because it need not have returned a pointer to the actual string buffer, and for data
because COW was a possible implementation strategy. Even if the buffer wasn't really const, modifying data
would have interfered with the invariants of COW.
But since C++11 COW is disallowed, c_str
and data
return the same pointer, and it's to the very buffer operator[]
would allow to modify. Why then is modifying the pointer via const_cast<CharT*>(s.data())
still explicitly undefined behavior? Is there a practical reason?
I'm not talking about a const
std::string
, but a non-const one.
And that right there is why that statement exists (and continues to exist even in C++17, when a non-const
data
was added). Because data
doesn't know that.
In a small-string optimized string
implementation, the string
object itself stores an array of characters. If that string
object is declared const
, then so too are its subobjects. Modifying objects declared as const
is UB.
By contrast, vector::data
has no such statement, because a const vector
always heap-allocates its array. So while the array is logically const
from the outside, it is technically well-defined (but you really, really shouldn't) to const_cast
the return value from a const
vector::data
, because you're modifying an object that was not created as const
.
If basic_string::data
had no such statement, an SSO-based implementation would be impossible, because it would be legal to modify the elements of a const string
, just like it's legal to modify the elements of a const vector
. But it can't be legal to modify it, because it might be a const
object whose data is stored internally.
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