On 06/02/18 16:22, Liu Hao wrote: > On 2018/2/6 23:03, Peter Breuer wrote: >> int main() { >> signed int x = 0x80000005u; >> unsigned int y = 0x00000002u; >> signed int z = x >> y; >> printf("0x%0x\n", z); >> return 0; >> } >> % gcc -std=c99 test.c >> test.c: In function 'main': >> test.c:6:3: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration] >> printf("0x%0x\n", z); >> ^ >> test.c:6:3: warning: incompatible implicit declaration of built-in function 'printf' >> >> (I'll live with that warning - just for the purpose of a clean example!) >> > > Well you could have declared the `printf()` function: > > extern int printf(const char *restrict format, ...); Or, far better : #include <stdio.h> <snip> > Clearly, the type of the operand on the right-hand side is not altered - > it remains `unsigned int`. > Equally relevantly, the left-hand side is not altered and remains "signed int". Basically, for operators that are at least roughly symmetrical (like *, +, /, -, etc.), arithmetic conversions are used to make both sides into the same types (of at least "int" size). But for asymmetric operators, like <<, >>, ?:, the comma operator, you get the integer promotions but they are handled separately. It all makes sense when you think about it.