sep-2001 libstdc++ outstanding
Paolo Carlini
pcarlini@unitus.it
Thu Oct 4 17:12:00 GMT 2001
>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;
}
More information about the Libstdc++
mailing list