[EMAIL PROTECTED] writes: > On Mon, Jun 12, 2006 at 12:32:36PM +0100, Andrew Haley wrote: > > [EMAIL PROTECTED] writes: > > > I want a reduced test case for this problem for bugzilla, but don't > > > really know the exact cause. I _think_ code is being improperly > > > optimized away, but I don't know. This function is part of a > > > BigInteger library, and works perfectly upto and including -O2, but > > > produces bogus results at -O3, unless I uncomment the debug_msg() > > > line, which just dumps the contents of 'i' to the screen. I'm > > > guessing that without it, the compiler fails to notice that i's > > > contents are being accessed via the _front8/_back8 pointers, and > > > throws the preceeding 'i' related code away. Heres the code: > > > > > > void Integer::export_bytes(Data& _buffer, PortMode _mode) const > > > { > > > debug_scope("export_bytes(Data&)"); > > > > > > Integer i(*this,1); > > > > > > if (_mode==SIGNED) { > > > if (*mBack & TOP_BIT) > > > i.grow(1,0); > > > if (sign()<0) > > > i.twoscomplement(); > > > } > > > > > > for (UnsignedW* p=i.mFront; p<=i.mBack; p++) > > > *p = host2little(*p); > > > > > > Unsigned8* _front8 = reinterpret_cast<Unsigned8*>(i.mFront); > > > Unsigned8* _back8 = _front8+(i.mSize*WORD_BYTES)-1; > > > if (_mode==UNSIGNED) > > > while (_back8!=_front8 and *_back8==0) > > > _back8--; > > > else if (mSign==1) > > > while (_back8!=_front8 and *_back8==0 and > > > !(*(_back8-1)&0x80)) > > > _back8--; > > > else > > > while (_back8!=_front8 and *_back8==0xff and > > > *(_back8-1)&0x80) > > > _back8--; > > > > > > //debug_msg(String("Force i\n")+i.dump()); > > > > > > _buffer.assign(_front8, _back8+1); > > > } > > > > > > Any thoughts on how to proceed? > > > > I think your code is broken. A reinterpret_cast from foo* to bar* is > > only well-defined if foo and bar are compatible types or one of > > {foo,bar} is type char. I can't be sure from your code, but I'm > > guessing that i.mFront is not declared as a pointer to Unsigned8, but > > as a pointer to an incompatible type UnsignedW. > > typedef unsigned long UnsignedW; > typedef unsigned char Unsigned8; > typdef std::vector<Unsigned8> Data; > > mFront is defined as UnsignedW*, an array of words constituting the > big integer.
OK. That should be fine, then. > Having converted the words from host to little endian with > host2little(), I am simply reading (exporting) the bytes out into a > vector using std::vector::assign(InputIter first, InputIter last) > > Seems legit, no? The only likely significant difference with -O3 is that small functions get inlined. I'm starting to be a little suspicious about host2little(). I wonder if that's well-defined. I'm just guessing here becasue I can't see the code. Is it possible for you to turn this into a small test case that anyone can run? Andrew.