tags:

views:

309

answers:

6

see this code

  #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) 

  int array[] = {23,34,12,17,204,99,16}; 

  int main() 

  { 

      int d; 

      for(d=-1;d <= TOTAL_ELEMENTS-2;d++) 
          printf("%d\n",array[d+1]); 

      return 0;

  }

now this loop won't run. sizeof() would return an unsigned value so TOTAL_ELEMENTS has an unsigned value. now , coming to the for loop, please tell me if the unary operator '-' works on signed int 2 or an implicit conversion takes place into unsigned and then the '-' operator works.

A: 

I suspect the unsigned type of sizeof() to propagate to the expression TOTAL_ELEMENTS-2 and then to both operands of d <= TOTAL_ELEMENTS-2. Inserting (int) juste before TOTAL_ELEMENTS fixes the issue.

mouviciel
+7  A: 

In your example d is converted to an unsigned int in the comparison. But -1 cannot be represented as an unsigned int value, so it is is converted to UINT_ MAX. To avoid this behaviour you can convert the right side of the comparison to an signed int by prepending (int).

See Understand integer conversion rules for details on integer conversion in C.

f3lix
That's the premise of the question. However, I think he's asking about arithmetic conversion rules.
Mark
I tried to point out why the code does not work and provided a link to a document that explains the promotion rules. Of course, to give a complete answer I should explained the rules and explained that 2 is converted to an unsigned it before it is substracted from TOTAL_ELEMENTS.
f3lix
+2  A: 

There's no unary operator in d <= TOTAL_ELEMENTS-2.

The TOTAL_ELEMENTS-2 reduces to an expression with a binary operator of -. This expression then becomes unsigned because one of its operands is unsigned.

In the case of d <= TOTAL_ELEMENTS-2, d's type is also converted to unsigned int for the same reason.

The relevant portion of the standard is section 6.3.1.8#1 (ISO/IEC 9899:1999) which says:

"Otherwise, 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."

Chris Young
+2  A: 

Yes, d also has an unsigned type in that expression, because of promotion, which is why the loop fails.

However, the question is whether the C compiler "thinks":

(unsigned) ((unsigned) 5 - (unsigned) 2)

i.e. promoting 2 to unsigned, or:

(unsigned) ((unsigned) 5 - (signed) 2)

i.e. subtraction taking operands of both types. Of course, it doesn't matter, as it would be the same operation for both. However, the whole point is that subtracting will return a value of one type, so theoretically it can only take arguments of that type. So it's the first (unsigned int 2).

P.S. (-2) is unary, while (5 - 2) is binary.

Mark
A: 

look , that '-' operator being unary was a stupid thing.forget it.it was the binary '-' , i realise.

when 2 is converted to unsigned int it becomes unsigned 2 , so TOTAL_ELEMENTS-2 has a value equal to unsigned 5 , and then when d is being converted to an unsigned int it gets a large positive value and
so the loop fails.

is that happening here??

and yes, i didn't write this code,this is some c puzzle i found on the web. thank ya all.

Yes, that is pretty much what happens.
f3lix
A: 

See also this similar question.

therefromhere