JB Enterprises - Johan BezemInterim Management & Consulting |
|
|
JB Enterprises - BlogWhy 32768 isn’t always the same as 0x8000Contrary to intuition, the C constants "32768" and "0x8000" have an identical representation (0x8000), 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 0x8000 (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 (or 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. #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); return; } When C_DECIMAL is considered long, the negation will invert 32 bits,
resulting in a representation 0xFFFF7FFF with type long; the cast is
superfluous. 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! March 5th, 2009
www.bezem.de:
© 1999 – 2024 by Johan Bezem, all rights reserved. |