I think the title explains pretty well what I'm asking so here is my code.
#include <stdio.h>
unsigned short u_short = 0xffff;
unsigned int u_int = 0xffffffff;
int main(){
printf("unsigned short = %d\n", u_short);
printf("unsigned int = %d\n", u_int);
return 0;
}
Here is my printout. printout picture
This is likely what happened in your C implementation:
In printf("unsigned short = %d\n", u_short);
, the unsigned short
value 65,535 is automatically converted to an int
with the same value. 1,2
The int
value 65,535 is passed to printf
, which formats it as “65535” due to the %d
conversion specification.
In printf("unsigned int = %d\n", u_int);
, the unsigned int
value 4,294,967,295 is passed to printf
; it is not converted to an int
. As an unsigned int
, 4,294,967,295 is represented with 32 one bits.
Because of the %d
conversion specification, printf
seeks an int
value that was passed as an argument. For this, it finds the bits passed for your unsigned int
, because an unsigned int
and an int
are passed in the same place in your C implementation, so the printf
looking for an int
finds the bits in the same place the calling routine put the unsigned int
bits. 3
When interpreted as an int
type, these bits, 32 ones, represent the value −1. 3 Given the −1 value, printf
formats it as “-1” due to the %d
conversion specification.
1 In many places in expressions, including arguments corresponding to ...
of a function declaration, values of types narrower than int
are automatically promoted to int
, as part of the integer promotions .
2 A C implementation could have an unsigned short
as wide as an int
, in which case this conversion would not occur. That is rare these days.
3 This is a description of what likely happened in your C implementation. The behavior is not defined by the C standard and may vary in other C implementations or even in different programs in your C implementation.
printf("unsigned int = %d\n", u_int);
is undefined behavior (UB) when u_int
is out of the positive int
range. Do not used "%d"
to print unsigned
.
Use printf("unsigned int = %u\n", u_int);
printf
has some anomalies due to the usual argument promotions . In particular, arguments of type char
and short
are promoted to int
when passing them to printf
. Usually this is fine, but sometimes it results in surprises like these. What you get when you promote an unsigned 16-bit 0xffff
to 32 bits is not 0xffffffff
.
printf
has some relatively little-known and relatively rarely-used modifiers to, in effect, undo those promotions and print char
and short
arguments as what they "really were". So you'll see more-consistent results if you tell printf
that you were actually passing a short
, like this:
printf("unsigned short = %hd\n", u_short);
printf("unsigned int = %d\n", u_int);
Now printf
knows that the argument in the first call was really a short
, so it treats it as such. On my machine, this now prints
unsigned short = -1
unsigned int = -1
(Now, with that said, it's arguably a bad idea to print unsigned integers with %d
, as the other answers and comments have explained.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.