Both libstdc++ and libc++ makes moved-from std::string
object empty, even if the original stored string is short and short string optimization is applied. It se
I know I thought about whether to zero the moved-from string when I was implementing the libstdc++ version, but I don't remember my reasons for deciding to zero it out. I think I probably decided that leaving the moved-from string empty would be following the principle of least astonishment. The most "obvious" state for a moved-from string is to be empty, even if sometimes being non-empty would perform slightly better.
As suggested in the comments, it avoids breaking any code that (maybe unintentionally) relied on the string being empty. I don't think that was one of my considerations though. C++11 code that relies on the COW string semantics will be broken by more than just moved-from strings being non-empty.
Worth noting is that at -O2
the current libstdc++ code compiles to fewer instructions compared to your suggested alternative. However something like this compiles even smaller, and is probably faster (I didn't measure it though, or even test it works):
basic_string(basic_string&& __str) noexcept
: _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator()))
{
memcpy(_M_local_buf, __str._M_local_buf, sizeof(_M_local_buf));
_M_length(__str.length());
if (!__str._M_is_local())
{
_M_data(__str._M_data());
__str._M_data(__str._M_local_data());
__str._M_set_length(0);
}
}