This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] RFC: reduce likelihood of fully-dynamic-string throwing on move
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: libstdc++ at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Thu, 16 Aug 2018 20:38:37 +0100
- Subject: [PATCH] RFC: reduce likelihood of fully-dynamic-string throwing on move
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?