I ran across the following example program and I don’t exactly understand it’s output:
#include <stdio.h>
int main( void ) {
unsigned char i, m =0xFF, n=0x1;
for ( i = 0; i != 8; i++,n+=n, m/=2 )
printf("%5x %5x %5x %5x %5x %5x\n", n,m,n&m,n|m,n^m,~n);
return 0;
}
It prints out:
1 ff 1 ff fe fffffffe
2 7f 2 7f 7d fffffffd
4 3f 4 3f 3b fffffffb
8 1f 8 1f 17 fffffff7
10 f 0 1f 1f ffffffef
20 7 0 27 27 ffffffdf
40 3 0 43 43 ffffffbf
80 1 0 81 81 ffffff7f
The problem is that last column. Since it’s unsigned char I would expect it to print out just 2 places in every column. ~n produces an unsigned char as it’s result, but it seems like it’s being cast to a signed 32 bit value and sign extended by the %5x specifier.
How is that possible, what’s going on here?
Integer types are promoted when they are used in arithmetic operations (this has nothing to do with
printf, by the way).So, for example,
Integer promotion causes various problems:
The two ways to truncate things are casting and masks. Use whatever you prefer.
Integer promotion doesn’t always happen, and it’s not the only kind of implicit cast. It’s also a bit subtle and the exact rules are difficult to remember. You only really need to worry about it if you’re working with 64-bit numbers, because
1U << 32could end up being0or1or something else entirely. (It’s often1on x86).