This is the mail archive of the mailing list for the libstdc++ project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: debug/vector anomalous behaviour

On Sat, 10 May 2008, PAOLO.CARLINI@ORACLE.COM wrote:

Ok, many thanks to everyone for the explanations. I'm going to commit to
mainline and 4_3-branch the below, tested x86_64-linux.

Sorry, maybe I am wrong but I suspect that this will only shift the problem to another place.

  $ pwd

  $ diff -u vector.old vector
  --- vector.old  2008-05-10 19:29:00.000000000 +0200
  +++ vector      2008-05-10 19:29:27.000000000 +0200
  @@ -362,7 +362,7 @@
         _M_requires_reallocation(size_type __elements)
          return __elements > this->capacity();
          return __elements > _M_guaranteed_capacity;

  $ pwd

$ g++ -o out -D_GLIBCXX_DEBUG

$ ./out


  $ ./out
      error: attempt to increment a singular iterator.

  Objects involved in the operation:
  iterator "this" @ 0x0xbfd2bfdc {
  type =
  IjSaIjEEEEENSt7__debug6vectorIjS6_EEEE (mutable iterator);
    state = singular;
    references sequence with type `NSt7__debug6vectorIjSaIjEEE' @ 0x0xbfd2bfdc

The patch should be something similar to:

--- vector.old	2008-05-10 19:29:00.000000000 +0200
+++ vector	2008-05-10 19:51:19.000000000 +0200
@@ -177,7 +177,16 @@

-      using _Base::capacity;
+      size_type
+      capacity() const
+      {
+	    return _M_guaranteed_capacity;
+	#else
+	    return _Base::capacity();
+	#endif
+      }
       using _Base::empty;

@@ -362,11 +371,7 @@
       _M_requires_reallocation(size_type __elements)
 	return __elements > this->capacity();
-	return __elements > _M_guaranteed_capacity;


i.e. the distinction between pedantic vs non-pedantic should be moved
inside the capacity() method.

But look, maybe I'm missing some details. I tested the patch against the test
case and also in our project. It seems to work correctly, indeed with the above
patch, compiling in pedantic mode, we discovered some assumptions that I was
making about the behaviour of the clear() method which are not specified by the
standard (so, thanks to the author of the debug mode because it is really useful!)

Stefano Soffia
Applied Formal Methods Laboratory
Department of Mathematics, University of Parma, Italy

(PS: the test case can be simplified a little. It is not very interesting,
however this is the code. The trick remains the same.)

#include <vector>
#include <algorithm>
#include <iterator>

typedef std::vector<unsigned> array_t;
typedef std::back_insert_iterator<array_t> bii_t;

array_t a;

int main() {
  // Push 3 elements.
  // Ensure that there is enough space for another element.
  // (1 + 3 = 4)
  if (a.capacity() < 4)
  // Add two new elements.
            a.begin() + 1,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]