signed/unsigned integer conversion for right shift seems against C99 rule

David Brown david@westcontrol.com
Tue Feb 6 15:31:00 GMT 2018


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.




More information about the Gcc-help mailing list