egcs 1.1.2 problem; shift on integers gives unexpected sign extension.

Michael Widenius monty@monty.pp.sci.fi
Tue Feb 29 08:46:00 GMT 2000


Hi!

>>>>> "Ross" == Ross Smith <ross.s@ihug.co.nz> writes:

Ross> From: "Michael Widenius" <monty@monty.pp.sci.fi>
>> 
>> Note that the I am just asking for adding an warning for this!  I am
>> not saying that gcc does anything wrong!
>> 
>> Note that not even 'gcc -Wall int-bug.c' gives any warnings for the
>> above code!
>> 
>> The above is a pitfall that will make 32 bit program that works fail
>> on 64 bit architectures.  Having a warning for this would making it
>> much easier to port code!  Do you really disagree that it's bad to
>> have warnings for potentially wrong code?  Can you see ANY
>> circumstances when the above behaveour is the one that the programmer
>> intended.  As you said, it's easy to fix with a cast, but if you are
>> porting some others code you may never find the place where this
>> happens.  The value that is shifted may be a struct element or a
>> typedef that may be unsigned on some system but signed on the 64 bit
>> Alpha.
>> 
>> The one reason programs are more unstable on Alpha than on other
>> systems is that some code that works perfectly on Intel will not work
>> on Alpha.  Having more and better warnings will just ensure that it
>> will be easier to get things to work on Alpha and this will benefit
>> everyone.

Ross> OK, I can see how this sort of thing could cause unexpected problems.
Ross> But I still say you're on the wrong track in thinking it has anything to
Ross> do with shifts. It's caused by the interaction of signed/unsigned
Ross> conversion and 32/64 bit conversion. The fact that the 32-bit value was
Ross> produced by a shift operation is a red herring.

I know; I only made a copy of some existing code that showed the
problem; You will of course get the same problem with most mixing of
operations with signed/unsigned arguments.

Ross> Personally I'd be in favour of a warning for *any* potentially
Ross> value-losing conversion (signed/unsigned in either direction, or from a
Ross> longer int to a shorter), but I suspect that would raise too many
Ross> complaints from old school hackers.

Adding this to -Wall or as a separate warning switch shouldn't offend
that many people!  The most likely pitfalls are probably

signed_var  << any_integer_var
signed_var  -  unsigned_var
unsigned_var - signed_var
(long) unsigned_var
(unsigned long) signed_var

Having a warning just for the above would probably make porting a lot easier.

Regards,
Monty


More information about the Gcc-bugs mailing list