Why 32768 isn’t always the same as 0×8000

Contrary to intuition, the C constants ’32768′ and ’0×8000′ have an
identical representation (0×8000), but possibly different types in C.
If you consider a processor with a 16-bit int type, and a 32-bit long
type, 32768 is considered long, whereas 0×8000 (and the octal variant
0100000) is considered ‘unsigned int’.

If you feel the need, check the C standard at
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf, page 55 at the
bottom, and the table at page 56. (look at Harbison & Steele, 5th edition, and look at section 2.7.1 page 24ff).

Normally, there is no problem when using such values, since the
representations are identical.
However, consider this small example:

#define C_DECIMAL     32768
#define C_HEXADECIMAL 0x8000

void main(int argc, char *argv[])
  volatile long long_dec = ((long)~C_DECIMAL);
  volatile long long_hex = ((long)~C_HEXADECIMAL);


When C_DECIMAL is considered long, the negation will invert 32 bits,
resulting in a representation 0xFFFF7FFF with type ‘long’; the cast is
When C_HEXADECIMAL is considered ‘unsigned int’, the negation will invert
16 bits, resulting in a representation 0x7FFF with type ‘unsigned int’;
the cast will then zero-extend to a ‘long’ value of 0x00007FFF.

Checking with a 16-bit integer compiler (CW7.1 ColdFire using ‘-intsize 2′):

0x00000000                    _main:
;                             main:
0x00000000  0x4E560000               link     a6,#0
0x00000004  0x518F                   subq.l   #8,a7
0x00000006  0x223CFFFF7FFF           move.l   #-32769,d1
0x0000000C  0x2D41FFF8               move.l   d1,-8(a6)
0x00000010  0x223C00007FFF           move.l   #32767,d1
0x00000016  0x2D41FFFC               move.l   d1,-4(a6)
0x0000001A  0x4E5E                   unlk     a6
0x0000001C  0x4E75                   rts

For those of you who do not know how to read assembler code I have made the differing values italic. So the compiler confirms the difference in behavior, and this is not a compiler error.

Lucky you if you have Lint to warn you. (Yes, I know, other tools will too, if you let them…)

Happy coding!

Tags: ,

Comments are closed.