This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
libstdc++/7106: vector<bool>::operator[] wrong on 64bit systems
- From: wolfgang dot bangerth at iwr dot uni-heidelberg dot de
- To: gcc-gnats at gcc dot gnu dot org
- Date: 24 Jun 2002 13:47:18 -0000
- Subject: libstdc++/7106: vector<bool>::operator[] wrong on 64bit systems
- Reply-to: wolfgang dot bangerth at iwr dot uni-heidelberg dot de
>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: