This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: string::assign apparent regression
- To: Roberto Bagnara <bagnara at cs dot unipr dot it>, libstdc++ at gcc dot gnu dot org
- Subject: Re: string::assign apparent regression
- From: Paolo Carlini <pcarlini at unitus dot it>
- Date: Fri, 14 Sep 2001 20:29:48 +0200
- Organization: Universita' della Tuscia
- References: <3BA1E0F1.96CC8158@cs.unipr.it>
- Reply-To: pcarlini at unitus dot it
Hi Roberto, hi all,
in the last hour, with the help of GDB I tried to understand in some
detail your testcase, after having verified that indeed 3 other reference
implementations of the C++ library behave as you expected ;-)
I traced back the problem not to a wrong terminator, but to the following
function in basic_string.tcc (lines 442-462):
--------------------------------------
template<typename _CharT, typename _Traits, typename _Alloc>
template<typename _ForwardIter>
basic_string<_CharT, _Traits, _Alloc>&
basic_string<_CharT, _Traits, _Alloc>::
_M_replace(iterator __i1, iterator __i2, _ForwardIter __k1,
_ForwardIter __k2, forward_iterator_tag)
{
size_type __dold = __i2 - __i1;
size_type __dmax = this->max_size();
size_type __dnew = static_cast<size_type>(distance(__k1, __k2));
if (__dmax <= __dnew)
__throw_length_error("basic_string::_M_replace");
size_type __off = __i1 - _M_ibegin();
_M_mutate(__off, __dold, __dnew);
// Invalidated __i1, __i2
if (__dnew)
_S_copy_chars(_M_data() + __off, __k1, __k2);
return *this;
}
---------------------------------------
What happens is that _M_mutate(__off, __dold, __dnew) is called with
__dold = 41 and __dnew = 23 *before* the actual copy operation
(_S_copy_chars) is carried out. Since the destination and source is the
very same string (i.e., aux) in your testcase, the aux string (as source)
is truncated at the 23th character ("../BenchCtiTr/apt/merge") and the
following copy operation (_S_copy_chars) produces a final aux = "merge".
Indeed, tentatively exchanging the _M_mutate and _S_copy_chars leads to
the expected behavior.
So, the trivial workaround is temporarily copying (aux, i+1,
string::npos) to a dummy string and then copying it back in aux. On the
other hand, the current structure of _M_replace should be heavily
modified if the current behaviouf of libstdc++-v3 is really incorrect wrt
the ISO standard.
Cheers,
Paolo.