tags:

views:

327

answers:

4

1.

main()
{

 if(-1<(unsigned char)1)
     printf("-1 is less than (unsigned char)1:ANSI semantics");
 else
     printf("-1 NOT less than (unsigned char)1:K&R semantics");
}

2.

int array[] = {23,41,12,24,52,11};
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))
main()
{
    int d = -1,x;
    if(d<=TOTAL_ELEMENTS -2)
        x = array[d+1];
}

The first convert unsigned char 1 to a signed variable in ANSI C, while the second program convert d to an unsigned int that makes the condition expression return false in ANSI C. Why did they behave differently?

+4  A: 

For the first one the right-hand side is an unsigned char, and all unsigned char values fit into a signed int, so it is converted to signed int.

For the second one the right-hand side is an unsigned int, so the left-hand side is converted from signed int to unsigned int.

See also this CERT document on integer conversions.

starblue
+1  A: 

starblue explained the first part of your question. I'll take the second part. Because TOTAL_ELEMENTS is a size_t, which is unsigned, the int is converted to that unsigned type. Your size_t is so that int cannot represent all values of it, so the conversion of the int to size_t happens, instead of the size_t to the int.

Conversion of negative numbers to unsigned is perfectly defined: The value wraps around. If you convert -1 to an unsigned int, it ends up at UINT_MAX. That is true whether or not you use twos' complement to represent negative numbers.

The rationale for C document has more information about that value preserving conversion.

Johannes Schaub - litb
A: 

Here's the way I remember how automatic conversions are applied:

  • if the operand sizes are different, the conversion is applied to the smaller operand to make it the same type as the larger operand (with sign extension if the smaller operand is signed)

  • if the operands are the same size, but one is signed and the other unsigned, then the signed operand is converted to unsigned

While the above may not be true for all implementations, I believe it is correct for all twos-complement implementations.

Michael Burr
A: 

See also this similar question.

therefromhere