no way to compare when less than two revisions

Differences

This shows you the differences between two versions of the page.


Last revision
blog:2017:11:27:2017-11-27_-_strings_and_sso [2017/11/27 21:50] – created basz
Line 1: Line 1:
 +====== 2017-11-27 - strings and SSO ======
  
 +since many years [[wp>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:
 +
 +<code>
 +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?
 +</code>
 +
 +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 127.0.0.1
Back to top
Valid CSS Driven by DokuWiki Recent changes RSS feed Valid XHTML 1.0