This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: 3.3.2 mips/ppc compiler bug?
- From: amodra at bigpond dot net dot au (Alan Modra)
- To: Martin Rivers <rivers at lexmark dot com>
- Cc: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 31 Dec 2003 08:49:08 +1030
- Subject: Re: 3.3.2 mips/ppc compiler bug?
- References: <3FF078CD.D0B3BED8@lpdev.prtdev.lexmark.com>
On Mon, Dec 29, 2003 at 01:56:13PM -0500, Martin Rivers wrote:
> However, it seems reasonable that the generation of the value
> of y using the division approach should not result in the same value as cmdxy.
No. Your problem is that the shift left operator for signed integers
does not have defined overflow semantics. Thus for int x, x << n is
not necessarily truncated to an int when x << n appears in an
intermediate expression.
It so happens that gcc currently does truncate (x << n) >> n, but from
my reading of ISO/IEC 9899:1999 it would not need to, while
(x << n) / (1 << n) is not truncated. You're relying on undefined
behaviour.
Note also that the shift right operator is also undefined on negative
signed values. Most people don't seem to know that a shift right
may not propagate sign bits. Unsigned values _do_ have defined
overflow semantics, so you should change your program to use unsigned
ints. If you really need to handle negative values then sign
extend values using something like the following example for an
18 bit field:
y = (((unsigned int) x & 0x3ffff) ^ 0x20000) - 0x20000;
--
Alan Modra
IBM OzLabs - Linux Technology Centre