-1

i find the output always carries a negative sign in the code below, although i indicated that the bits for the variable x are for unsigned integers in the initiation statement.

why ~x produces a negatively signed number while there is no bit assigned for the sign of the number to be reflected in the first place?

#include <stdio.h>
void main() {
    unsigned int x = 11;
    printf("not x=%d", ~x);
}
muhzi
  • 119
  • 2
  • 14

2 Answers2

1

This behavior is dependent on the platform, but the basic answer is that printf doesn't know that the thing you're passing was declared as unsigned. It's just a value. if you use the %d format, that value will be interpreted as a signed integer. If you use %u, it will be interpreted as unsigned. On a processor using two's complement representation, a value with the most significant bit set is negative. Since ~11 has that bit set, it is shown as a negative number.

Andy Schweig
  • 6,597
  • 2
  • 16
  • 22
  • 3
    The behaviour is *not* implementation-defined, it is *undefined* by 7.21.6.1.p9. – Kerrek SB Dec 08 '16 at 16:25
  • @Andy Schweig u r saying that the representation of the bits changed the result and that was changed by indicating different output formulas (%d,%u)? please correct me if i am wrong .. – muhzi Dec 08 '16 at 16:44
0

It's about the interpretation that printf gives to the parameter you pass.

unsigned int x = 11;
printf("not x=%d", ~x);

During the function call the default argument promotions will pass ~x to printf as type unsigned int. The default argument promotions are applied due to va_args from the signature of printf.

Also, integer promotions are applied for computing the ~x -- from 6.5.3.3 Unary arithmetic operators:

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. If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E.

So you pass an unsigned integer, but printf will cast it to int, as %d expects to find an int.

alinsoar
  • 15,386
  • 4
  • 57
  • 74