This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Option to make unsigned->signed conversion always well-defined?
Em 05-10-2011 17:11, Ulf Magnusson escreveu:
> Hi,
>
> I've been experimenting with different methods for emulating the
> signed overflow of an 8-bit CPU.
You would like to check whether a 8-bit signed addition will overflow or
not, given the two operands. Is that correct?
As you used the word `emulating', I am assuming that your function will
not run by the mentioned CPU.
Does this 8-bit CPU use two's complement representation?
> 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.
I believe the cast from unsigned int to int8_t is implementation-defined
for values that can't be represented in int8_t (e.g. 0xff). A kind of
`undefined behavior' as well.
I tried:
bool overflow(unsigned int a, unsigned int b) {
const unsigned int sum = a + b;
return ((a & 0x80) == (b & 0x80)) && ((a & 0x80) != (sum & 0x80));
}
But it is not as efficient as yours.
--
Pedro Pedruzzi