0
#include <stdio.h>
int main() {
    unsigned char a = 5;
    printf("%d\n",~a);
    printf("%d\n",a=~a);
    return 0;
}

According to the accepted answer here Negation inside printf , in the first printf, a should get promoted to an int and the output should be a large negative number. But the output of the first printf is -6. Can you please explain why the output is -6 and why the char is not promoted to int in this case?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Stupid Man
  • 885
  • 2
  • 14
  • 31

3 Answers3

2

Can you please explain why the output is -6 and why the char is not promoted to int in this case?

Not really, because it is being promoted to an int - and, as an int, inverting all the bits will (assuming two's-complement notation and no overflow) convert a positive n value into the negative value, -(n+1).

This modification to your code may demonstrate what's happening:

#include <stdio.h>
int main()
{
    int a = 5;
    printf("%d\n", ~a); // Prints -6
    printf("%d\n", a = (unsigned char)~a); // Prints 250 - lower 8 bits of the int
    return 0;
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
1

It is getting promoted and ~5 == -6 in two's complement. Assuming two's complement, the bitwise negation of a small positive number will yield a small negative number. The number will appear large only when viewed as an unsigned, which is what "%X" in the linked answer does.

(BTW, the number in the linked answer should also have been cast to unsigned before being printed as "%X", because printf technically requires exact correspondence between the conversion specifier and the type of the passed argument).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
1

For two's complement internal representations if you have an integer value x then the expression

x + ~x + 1

is equal to 0.

So for this declaration

unsigned char a = 5;

the operand of the expression ~a will be promoted to the type int.

So you will have that

~a + a + 1 = 0

that is

~a + 5 + 1 = 0

And as a result the value of the expression ~a

~a = -5 -1 = -6

In binary notation it looks like (provided that the type int occupies 4 bytes)

a ( = 5 ) = 00000000 00000000 00000000 00000101
~a        = 11111111 11111111 11111111 11111010

a + ~a    = 11111111 11111111 11111111 11111111

The last binary value is the representation of -1 in the type int.

In this call

printf("%d\n",a=~a);

at first the expression ~a was truncated to an object of the type unsigned char dues to the assignment

a=~a

That is the expression will have a non-negative number.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335