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. 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? > Andrew. >