https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102048

            Bug ID: 102048
           Summary: __gnu_cxx::rope.erase(size_t __p) implementation seems
                    to be wrong
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: fstqwq at foxmail dot com
  Target Milestone: ---

In ext/rope from all versions of gcc I could refer to (see
https://github.com/gcc-mirror/gcc/blame/master/libstdc%2B%2B-v3/include/ext/rope#L2407,
the last change is made 17 years ago), the implementation of
__gnu_cxx::rope.erase(size_t) is:

      // Erase, single character
      void
      erase(size_type __p)
      { erase(__p, __p + 1); }

The comment said it will erase a single character from rope. However, the
function actually erase (__p + 1) characters starting from position __p by
calling erase(size_t, size_t) commented as "Erase, (position, size) variant.",
which is just defined above the erase(size_t) version.

You can test the function by the following code:

#include <bits/stdc++.h>
#include <ext/rope>
int main() {
        __gnu_cxx::rope<int> R;
        for (int i = 0; i < 9; i++) R.push_back(i);
        R.erase(2);
        for (int i = 0; i < 4; i++) std::cout << R[i] << std::endl; 
}

If erase functions normally or replace erase(2) with erase(2, 1), it's expected
to see 0 1 3 4. It turned out to be 0 1 5 6, that erases 3 elements starting
from 2.

Reply via email to