unsigned short int i = 0;
 printf("%u\n",~i);
Why does this code return a 32 bit number in the console? It should be 16 bit, since short is 2 bytes.
The output is 4,294,967,295 and it should be 65,535.
                        
                            
                        
                        
                            On
                            
                                                    
                    
                When you pass an argument to printf and that argument is of integer type shorter than int, it is implicitly promoted to int as per K&R argument promotion rules. Thus your printf-call actually behaves like:
printf("%u\n", (int)~i);
Notice that this is undefined behavior since you told printf that the argument has an unsigned type whereas int is actually a signed type. Convert i to unsigned short and then to unsignedto resolve the undefined behavior and your problem:
printf("%u\n", (unsigned)(unsigned short)~i);
                        
                        
                            
                        
                        
                            On
                            
                                                    
                    
                It's because the arguments to printf() are put into the stack in words, as there is no way inside printf to know that the argument is short. Also by using %u format you are merely stating that you are passing an unsigned number.
                        
                            
                        
                        
                            On
                            
                                                    
                    
                N1570 6.5.3.3 Unary arithmetic operators p4:
The result of the ~ operator is the bitwise complement of its (promoted) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and the result has the promoted type. ...
Integer type smaller than int are promoted to int. If sizeof(unsigned short) == 2 and sizeof(int) == 4, then resulting type is int.
And what's more, printf conversion specifier %u expects unsigned int, so representation of int is interpreted as unsigned int. You are basically lying to compiler, and this is undefined behaviour.
%uexpects anunsigned int; if you want to print anunsigned short int, use%hu.EDIT
Lundin is correct that
~iwill be converted to typeintbefore being passed toprintf.iis also converted tointby virtue of being passed to a variadic function. However,printfwill convert the argument back tounsigned shortbefore printing if the%huconversion specifier is used:Emphasis mine.
So, the behavior is not undefined; it would only be undefined if either
ior~iwere not integral types.