3

I want to know what is the reason of the output of the following codes:

unsigned short a=10,aa=-1;
if(a>-1)
  printf("surprise");
else 
  printf(" No surprise");

This gives output "Surprise"

 unsigned int a=10,aa=-1;
    if(a>-1)
      printf("surprise");
    else 
      printf("No surprise");

This gives output "No Surprise"

and

unsigned short a=10,aa=-1;
if(a>aa)
   printf("surprise");
else 
  printf("No surprise");

This gives the output "No Surprise"

pratikvasa
  • 1,897
  • 20
  • 24
  • 1
    [Mandatory viewing](http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-7-of-n). – Kerrek SB Sep 28 '13 at 12:10
  • 2
    You need to be able to reason these things out if you hope to become a developer. There are no surprises in the output of these -- even though your first example's output wrongly suggests otherwise. – mah Sep 28 '13 at 12:12
  • 2
    search for "unsigned integer overflow" and "integer promotion". –  Sep 28 '13 at 12:12
  • Output is as expected, but comparison of unsigned with signed -1 is UNDEFINED BEHAVIOR Rely on it at your peril - the computer is entitled to shoot green sparks out of your nose if it wishes. – camelccc Sep 28 '13 at 13:48

3 Answers3

2

Its integer promotion specified in C language. Basically, the arithmetic are done in signed rather than short. I assume you use a 32 bit and above CPU.

unsigned short a=10,aa=-1;
if(a>-1)
  printf("surprise");
else 
  printf(" No surprise");

The above translate into assembly below. So, what you get is signed int(10) compare with signed int (-1), as indicated by the assembler using jle instruction.

unsigned short a=10,aa=-1;
000C17DE  mov         eax,0Ah  
000C17E3  mov         word ptr [a],ax  
000C17E7  mov         eax,0FFFFh  
000C17EC  mov         word ptr [aa],ax  
    if(a>-1)
000C17F0  movzx       eax,word ptr [a]  
000C17F4  cmp         eax,0FFFFFFFFh  
000C17F7  jle         wmain+52h (0C1812h)

As for part 2, it unsigned compares 0x0A with 0xFFFFFFFF. For part 3, it signed compares 0x0A with 0xFFFF

Tay Wee Wen
  • 468
  • 3
  • 13
2

See this Stack Exchange question:

In a C expression where unsigned int and signed int are present, which type will be promoted to what type?

In the response from AProgrammer, the complete rules are listed. In your first case, the 4th rule applies (-1 is signed integer, which can represent all the values of unsigned short, therefore the unsigned short is promoted to signed integer). In your second case, the 3rd rule applies (signed integer cannot represent all values of unsigned integer, so it is changed to unsigned integer). In your third case, the -1 is converted to unsigned short and then the first rule applies.

In general I like to avoid confusion by converting all vars to the same signed type (large enough to hold the range I expect) before doing any comparisons.

Community
  • 1
  • 1
willus
  • 501
  • 3
  • 7
1

You're initializing an unsigned variable to -1. Unsigned variables can only represent non-negative numbers. C does not specify what representation is used for negative signed numbers, so when you assign a negative number of an unsigned variable, you invoke undefined behavior. At that point, the program can print "surprise", "no surprise", or "happy birthday".

On a 2s complement machine (which most modern CPUs are), -1 has the same bit representation as the largest unsigned value, so it's likely that you've initialized aa to the maximum representable value. If that's what you actually intend, you should use aa = USHRT_MAX instead.

pburka
  • 1,434
  • 9
  • 12