Andrew Haley <aph@xxxxxxxxxx> writes: > On 10/05/2011 09:11 PM, Ulf Magnusson wrote: >> Hi, >> >> I've been experimenting with different methods for emulating the >> signed overflow of an 8-bit CPU. The method I've found that seems to >> generate the most efficient code on both ARM and x86 is >> >> bool overflow(unsigned int a, unsigned int b) { >> const unsigned int sum = (int8_t)a + (int8_t)b; >> return (int8_t)sum != sum; >> } >> >> (The real function would probably be 'inline', of course. Regs are >> stored in overlong variables, hence 'unsigned int'.) >> >> Looking at the spec, it unfortunately seems the behavior of this >> function is undefined, as it relies on signed int addition wrapping, >> and that (int8_t)sum truncates bits. Is there some way to make this >> guaranteed safe with GCC without resorting to inline asm? Locally >> enabling -fwrap takes care of the addition, but that still leaves the >> conversion. > > inline int8_t as_signed_8 (unsigned int a) { > a &= 0xff; > return a & 0x80 ? (int)a - 0x100 : a; > } > > int overflow(unsigned int a, unsigned int b) { > int sum = as_signed_8(a) + as_signed_8(b); > return as_signed_8(sum) != sum; > } This version looks good to me. In general there are two cases: if you have a wider type, and if you do not. If you have a wider type, do what Andrew suggests. If you do not have a wider type, do the addition using an unsigned type, and see if the result is smaller than either of the operands. Ian