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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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, ...);

> % ./a.out
> 0xe0000001
>   ^ SIGNED right shift
> 
> OK, so x>>y was done signed. That means both x,y were converted to
> signed int (trivially).

No. See below.

> 
> However, that seems against C99 rules, which seem to say one should
> convert to unsigned int in mixed sign equal rank situations.
> 
> First: NO INTEGER PROMOTION is done, by this rule
> 
>   any operand whose type ranks lower than int is automatically converted
>   to the type int, provided int is capable of representing all values of
>   the operand's original type.  If int is not sufficient, the operand is
>   converted to unsigned int.
> 
> Both x and y are int, so do not rank "lower than int". Rule does not
> apply. All as is. So INTEGER CONVERSION applies from there:

It doesn't.

I don't have C99 at hand, so I will quote C11 (WG14 N1570) for you:

```
6.5.7 Bitwise shift operators
  ...
  Semantics
3 The integer promotions are performed on each of the operands.  ...
```

Note that the standard references _the integer promotions_, in contrast
to what you see elsewhere:

```
6.5.5 Multiplicative operators
  ...
  Semantics
3 The usual arithmetic conversions are performed on the operands.
```

```
6.5.9 Equality operators
  ...
  Semantics
4 If both of the operands have arithmetic type, the usual arithmetic
  conversions are performed.
```

Clearly, the type of the operand on the right-hand side is not altered -
it remains `unsigned int`.




-- 
Best regards,
LH_Mouse




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux