2017-11-27 - strings and SSO

since many years C++ standard not only prohibits copy-on-write (aka: CoW) strings implementation, but even allows implementations to use small-string-optimization (aka: SSO). i've recently came across an interesting bug, “using” this corner case, in a code similar to this:

std::string value_;
// ...
std::string one{"foo"};
char const* ptr = one.data(); // 1
std::string two{ std::move(one) };
// ... 'one' no longer exists here ...
// ... 'two' is still here ... 
cout << ptr; // valid or not?

it used to work on one of the compilers, but not on the other.

it turned out that one of the implementations used SSO, while other did not. when there was no SSO, line (1) was ok, since one.data() returned the very same, heap-allocated pointer, that later on was passed for ownership to the string two.

however when SSO kicks in, short sting may be kept on stack! no memory allocation is performed, but also one.data() will never be equal to two.data(), regardless if two is copy- or move- initialized. the net effect is dangling pointer and UB is unleashed.

so is the code correct or not? NO – it is NOT correct! why? because SSO is valid, standard-compliant implementation feature of std::string and one may not rely on it being (or not being) there. even if your compiler does not implement it yet, it might still break badly with next compiler update. and to make things worse, it will break silently.

lesson learned is that one should never assume neither any particular state of moved-from object, nor a state of pointer/reference generated out of it, unless this is explicitly stated inside the library. one famous example of such special case are std::shared_ptr and std::unique_ptr that, when moved from, guarantee to be nullptr.

by default however, there are no guarantees for other objects. technically speaking moved-from object must only be able to safely destroy itself (i.e. call d-tor). nothing more.

blog/2017/11/27/2017-11-27_-_strings_and_sso.txt · Last modified: 2021/06/15 20:09 by
Back to top
Valid CSS Driven by DokuWiki Recent changes RSS feed Valid XHTML 1.0