[PATCH] RFC: reduce likelihood of fully-dynamic-string throwing on move

Jonathan Wakely jwakely@redhat.com
Thu Aug 16 19:38:00 GMT 2018


With --enable-fully-dynamic-string the COW basic_string move
constructor is noexcept(false), because it has to allocate a new empty
rep for the moved-from string.

If we did this, it would only throw when the string we're moving from
is "leaked" (that is, there are potentially pointers, references or
iterators into the string that prevent it being shared):

--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -3575,7 +3575,10 @@ _GLIBCXX_END_NAMESPACE_CXX11
 #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
        __str._M_data(_S_empty_rep()._M_refdata());
 #else
-       __str._M_data(_S_construct(size_type(), _CharT(), get_allocator()));
+       if (__str._M_is_leaked())
+         __str._M_data(_S_construct(size_type(), _CharT(), get_allocator()));
+       else
+         (void) _M_rep()->_M_refcopy();
 #endif
       }

If the string is sharable then a move can just increase the refcount,
which won't throw.

This would break the guarantee that a moved-from string is empty, but
the standard doesn't guarantee that anyway, and we don't leave COW
strings empty after move assignment.

Thoughts?




More information about the Libstdc++ mailing list