3

This is a question relating the c99 standard and concerns integer promotions and bitwise negations of unsigned char.

In section 6.5.3.3 it states that:

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.

Am I understanding that correctly when I say that, that means that:

unsigned int ui = ~ (unsigned char) ~0; // ui is now 0xFF00.

My confusion stems from a discussion with a collegue where he is seeing the following behaviour in our compiler.

unsigned char uc = 0;
unsigned char ucInverted = ~0;

if( ~uc == ~0 )              // True, obviously
if( ~ucInverted == ~(~0) )   // False as it evaluates to: 0xFF00 == 0x0000
if( ~uc == ucInverted )      // False as it evaluates to: 0xFFFF == 0x00FF
if( uc == ~ucInverted )      // False as it evaluates to: 0x0000 == 0xFF00

This behaviour is confirmed with gcc.

Is it possible to get proper expected char comparisons where each of these cases will evaluate to true?

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
Kenneth
  • 1,167
  • 1
  • 13
  • 26
  • Read [in this answer](http://stackoverflow.com/questions/17796041/calculating-ranges-of-data-types-in-c/17796122#17796122) If `~0` is a trap representation, then the behavior is undefined. – Grijesh Chauhan Sep 23 '13 at 10:44
  • @GrijeshChauhan: These are unsigned, the trap representation in this case is irrelevant. see also footnote 53 in 6.2.6.2 linked from the linked answer. – Hasturkun Sep 23 '13 at 10:55
  • 2
    @Hasturkun: `~0` is not unsigned... – Oliver Charlesworth Sep 23 '13 at 10:56
  • @OliCharlesworth: True. As far as I understand though, still not an issue as there's wording stating that "no arithmetic operation on valid values can generate a trap representation other than as part of an exceptional condition such as an overflow." for signed types as well. – Hasturkun Sep 23 '13 at 14:06
  • Possible duplicate of [Confusion with C ~ operator (bitwise Not) and comparing char variables](https://stackoverflow.com/questions/7940815/confusion-with-c-operator-bitwise-not-and-comparing-char-variables) – phuclv May 07 '19 at 01:47

1 Answers1

2

~uc is of type int (value 0xFFFF). ucInverted is of type unsigned char (value 0xFF), which is then promoted to int (value 0x00FF). Thus they are not equal.

I guess you could do if ((unsigned char)~uc == ucInverted). Both operands will still undergo promotion, but they will have identical values before the promotion.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680