Thanks for the feedback. 2010/6/16 Bakul Shah <[email protected]>: > 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. > >
-- Hugo
