Niteesh
Niteesh

Reputation: 121

Why is the output wrong?

#include<stdio.h>

main()
{
      unsigned  x=1;
      signed char y=-1;
      clrscr();
      if(x>y)
       printf("x>y");
      else
     printf("x<=y");
}

A signed character has an increased value from -128 to 127. So the expected out put should have been 'x>y', but it isn't. The compiler gives the output - "x<=y". Can you explain why?

Upvotes: 1

Views: 139

Answers (6)

TOC
TOC

Reputation: 4446

When the compiler see comparing an unsigned int with signed int it promote the signed int to unsigned, this mean adding this (in linux box) to the signed one:

#define UINT_MAX    (~0U) (defined in this header file : /include/linux/kernel.h)

So now you are comparing UINT_MAX - 1 (UINT_MAX + y) with x, which explain clearly the output.

Edit : to be more clear : on 32 bits machine ---> UINT_MAX = 2 147 483 648 = 2**31

Regards.

Upvotes: 0

steffen
steffen

Reputation: 8958

Get used to compile with all warnings, i.e. in the case of gcc:

gcc -Wall -Wextra -pedantic source.c -o prog

In your case the flag -Wextra give the following message:

warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

That doesn't explain why, but it warns you at least ;) .

The explanation is that a signed variable evaluating to -1 is equal to an unsigned evaluating to UINT_MAX when compared with a relational operator.

The compiler has to do something well defined in that case and this is what people came up with...

Upvotes: 0

md5
md5

Reputation: 23699

C11 §6.8 al3 p95 :

If both of the operands have arithmetic type, the usual arithmetic conversions are performed.

C11 §6.3.1.8 al1 p53 :

[...] if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

So y will be promote to an unsigned type, and will be greater than x (1).

Upvotes: 2

Maksim Skurydzin
Maksim Skurydzin

Reputation: 10541

In your case signed char is converted to unsigned int, thus we are getting a big positive integer instead of -1. Here is an extract from ANSI C standard draft that explains what happens during usual arithmetic conversions that took place.

3.2.1.5 Usual arithmetic conversions

Many binary operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions: First, if either operand has type long double, the other operand is converted to long double . Otherwise, if either operand has type double, the other operand is converted to double. Otherwise, if either operand has type float, the other operand is converted to float. Otherwise, the integral promotions are performed on both operands. Then the following rules are applied: If either operand has type unsigned long int, the other operand is converted to unsigned long int. Otherwise, if one operand has type long int and the other has type unsigned int, if a long int can represent all values of an unsigned int, the operand of type unsigned int is converted to long int ; if a long int cannot represent all the values of an unsigned int, both operands are converted to unsigned long int. Otherwise, if either operand has type long int, the other operand is converted to long int. Otherwise, if either operand has type unsigned int, the other operand is converted to unsigned int. Otherwise, both operands have type int.

Upvotes: 0

Matrix 2.0
Matrix 2.0

Reputation: 25

in comparison, if one operand is unsigned, then the other operand is implicitly converted into unsigned if its type is signed!

more to found here : Signed/unsigned comparisons

Upvotes: 0

cnicutar
cnicutar

Reputation: 182639

In the comparison the signed char gets converted to an unsigned int and thus looks like a really big value. I would expect the compiler to warn you - i.e. something in the lines "comparing signed and unsigned stuff is confusing".

This conversion is mandated under "Relational operators":

If both of the operands have arithmetic type, the usual arithmetic conversions are performed.

Upvotes: 7

Related Questions