This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: sep-2001 libstdc++ outstanding
- To: libstdc++ at gcc dot gnu dot org
- Subject: Re: sep-2001 libstdc++ outstanding
- From: Paolo Carlini <pcarlini at unitus dot it>
- Date: Fri, 05 Oct 2001 02:10:34 +0200
- CC: bkoz at redhat dot com
- Organization: Universita' della Tuscia
- Reply-To: pcarlini at unitus dot it
>2001-09-14
> string::assign apparent regression
> http://gcc.gnu.org/ml/libstdc++/2001-09/msg00047.html
> http://gcc.gnu.org/ml/libstdc++/2001-09/msg00096.html
> * this should go in. Phil, Loren, Gaby? *
I would like to add to Kosnik's heads up, that my patch (or better, a slightly
polished version of it, see below) touches basic_string::_M_replace and
therefore, besides solving the specific regression that Roberto pointed out,
also impacts the behaviour of other string member functions whenever source and
destination ranges are overlapped (an arguably "pathological" case). Consider,
for instance the following snippet involving string::replace:
std::string aux = "../BenchCtiTr/apt/mergesort_ap_variant.pl";
aux.replace(aux.begin()+5, aux.begin()+20,
aux.begin()+10, aux.begin()+15);
std::cout << aux << std::endl;
aux = "../BenchCtiTr/apt/mergesort_ap_variant.pl";
aux.replace(aux.begin()+10, aux.begin()+15,
aux.begin()+5, aux.begin()+20);
std::cout << aux << std::endl;
The output is:
libstdc++v2
-----------
../Bergesorgesort_ap_variant.pl
../BenchCtnchCtnchCtnchCtpt/mergesort_ap_variant.pl
current libstc++-v3
-------------------
../Bergesorgesort_ap_variant.pl
../BenchCtnchCtiTr/apt/mept/mergesort_ap_variant.pl
current libstdc++-v3 + my patch
-------------------------------
../BeiTr/argesort_ap_variant.pl
../BenchCtnchCtiTr/apt/mept/mergesort_ap_variant.pl
Indeed, only in the last case the semantics of string::replace is consistent
with that corresponding to the non-overlapping case, and, in my reading of the
ISO/ANSI standard (cross checked on the comp.std.c++ list) this is the right
thing to do (the standard does not distinguish or mention the overlapping case,
right?).
Thanks for your attention,
Paolo.
--- basic_string.tcc.orig Wed Oct 3 23:29:20 2001
+++ basic_string.tcc Wed Oct 3 23:33:39 2001
@@ -453,10 +453,14 @@
if (__dmax <= __dnew)
__throw_length_error("basic_string::_M_replace");
size_type __off = __i1 - _M_ibegin();
+ // Save concerned source string data in a temporary
+ basic_string __temp(__k1, __k2);
_M_mutate(__off, __dold, __dnew);
- // Invalidated __i1, __i2
+ // Invalidated __i1, __i2 (and clobbered original source string
+ // data when destination string == source string and the string
+ // is unshared)
if (__dnew)
- _S_copy_chars(_M_data() + __off, __k1, __k2);
+ _S_copy_chars(_M_data() + __off, __temp.begin(), __temp.end());
return *this;
}