I have the following sample code:
uint64_t x, y;
x = ~(0xF<<24);
y = ~(0xFF<<24);
The result would be:
x=0xffff
You have undefined behavior in your program so anything might happen.
int, which is equivalent to signed int. On this particular platform, int is apparently 32 bits.int.int so no implicit type promotions take place. The result of the << operation is therefore also a (signed) int.int as a non-negative value, so everything is ok.int! Here, undefined behavior is invoked and anything might happen. ISO 9899:2011 6.5.7/4:
"The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros." /--/
"If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
So the expression 0xFF<<24 can't be used. The program is free to print any garbage value after that.
But if we ignore that one and focus on 0x0F<24:
int. The ~operator is applied to this. Bugs like this is why the coding standard MISRA-C contains a number of rules to ban sloppy use of integer literals in expression like this. MISRA-C compliant code must use the u suffix after each integer literal (MISRA-C:2004 10.6) and the code is not allowed to perform bitwise operations on signed integers (MISRA-C:2004 12.7).