On Wed, 16 Jun 2010 11:11:09 +0200 hugo rivera <[email protected]>  wrote:
> Can someone clarify why the program included outputs 'AB000000' (as I
> expect) on 32 bit systems and 'FFFFFFFFAB000000' on 64 bit systems?
> where all those 1's came from? what's the portable way of doing this?
> sorry for newbie questions like this.
> 
> 
>        unsigned long l;
>         unsigned char c;
> 
>         l = 0L;
>         c = 0xAB;
>         l |= c << 24;
>         printf("%lX\n", l);

For use of C on non-plan9 machines I would recommend
downloading the last draft of the C9x standard as a ready
reference.  Google for n843.

As per Section 6.5.7 of C9x, both operands of << must be of
"integer type" and the result type is that of the left
operand. Since sizeof c < sizeof(int), it is promoted.  Now
6.3.1.2 says "if an int can represent all values of the
original type, the value is converted to an int". So c is
first converted to an int which means c << 24 is an integer
and -ve. Since an int is smaller than a long (in your case)
it is promoted to a long. Changing the |= statement to

         l |= (unsigned)c << 24;

should give you what you want.

Reply via email to