C/C++ char comparison riddle (last update: 2013-02-12, created: 2013-02-12) back to the list ↑
This riddle is based on code I was asked to look at (in that specific case due to the code's nature this bug didn't break anything, but it was there and would break something in the future).

Question: Will this code output "YES" or "NO" ?

#include <stdio.h>
int main(void) {
  char x = 0xff;

  if(x == 0xff)
    puts("YES");
  else
    puts("NO");

  return 0; 
}


Scroll down for the solution.

Keep scrolling...

Keep scrolling...

Keep scrolling...


As usual, there is no single answer, however on x86 with most modern compilers it will print "NO".

screenshot of the test using g++ and cl.exe; both print NO

Let's walk through this:
1. Type char is commonly implemented as signed char with range from -128 to 127.
2. Immediate value 0xff is an int which value is 255.
3. So char x = 0xff is actually signed char x = (signed char)255.
4. 255 doesn't fit into a signed char and since it's int-class the overflow is considered undefined behavior...
5. ...but, the actual behavior on x86 with most compilers is just to reinterpret the lowest byte of the int as a signed char, which leads us to x being assigned a signed char value of -1.
6. Going further there is a comparison between x and 0xff which, as said, is an int immediate value of 255.
7. Of course in C/C++ we cannot just compare two different types, so an integer promotion takes place - the signed char gets converted to an int in this case, so we get: if((int)x == 0xff).
8. The -1 (binary FF) value from x is sign-extended to again -1 (binary FFFFFFFF for 32-bit int).
9. And so we get to the final comparison which looks like this: if(-1 == 255), which of course is not equal and so evaluates to 0 or false.

There are two important things to note about the above:
A. In point 4 and 5 I assume an implementation defined behavior in this case. If the behavior would be really undefined, who knows what would happen in the end.
B. If the char type would be implemented as unsigned char this code would be fully defined and would print "YES".

And that's that.
【 design & art by Xa / Gynvael Coldwind 】 【 logo font (birdman regular) by utopiafonts / Dale Harris 】