This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC 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]

libstdc++/7106: vector<bool>::operator[] wrong on 64bit systems


>Number:         7106
>Category:       libstdc++
>Synopsis:       vector<bool>::operator[] wrong on 64bit systems
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 24 06:56:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Wolfgang Bangerth
>Release:        unknown-1.0
>Organization:
>Environment:
SparcV9 (64bit), sparc-sun-solaris2.9
>Description:
Using vector<bool>::operator[] goes wrong when on a 64bit
system: somehow computing the bit index does not take into
account that sizeof(int)==32 but sizeof(int*)==64. Rather, 32 bit is assume, leading the equality of the 32nd with the 0th bit, 33rd with the first, and so on. I'd think that the fix is trivial, when one knows where to look, but I got lost in the header file and all the class local typedefs, sorry.

The attached program demonstrates the problem: it initializes a vector of 40 elements, prints it (all zero, ok), the sets the zeroth element and prints it again. The output is
  examples/step-1> ./a.out 
  0000000000000000000000000000000000000000
  1000000000000000000000000000000010000000
Note thet spurious second "1" in the second line.

This is the program:
----------------------------------------------
#include <vector>
#include <iostream>

void print (std::vector<bool> &v) {
  for (unsigned int i=0; i<v.size(); ++i)
    std::cout << v[i];
  std::cout << std::endl;
};


int main ()
{
  const unsigned int N = 40;
  std::vector<bool> v (N, false);
  print (v);

  v[0] = true;
  print (v);
};
---------------------------------------
Compile it with 
  g++ -m64 x.cc
on sparcv9.

There are more oddities:
- first, the _Bit_reference structure exports its members
  publicly. I guess, there's a "private" missing at the
  start of the class. The same applies to a number of other
  classes in the file.

- Well, I dug further into the header file: the reason the
  original problem is happening is this: put the following
  two lines into the program above (this uses the fact that
  members are not private :-):
    std::cout << v[0]._M_p << ' ' << v[0]._M_mask 
              << std::endl;
    std::cout << v[32]._M_p << ' ' << v[32]._M_mask 
              << std::endl;
  Clearly the masks for the two elements should be  
  different. Nevertheless, this is the output on my system:
    0x100103180 1
    0x100103180 1

Ah, I think I now got it: the data is stored as unsigned longs, but in _Bit_iterator::operator* a reference is
created with pointer base and bit offset   1U<<_M_offset.
This should likely read  1UL, no?

There are two places in the file where 1U appears, one in the const, and in the non-const bit iterator. If I change them both, the test succeeds. So I guess this is also the right fix.

Regards
  Wolfgang
>How-To-Repeat:

>Fix:
read the above.
>Release-Note:
>Audit-Trail:
>Unformatted:


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