1

Possible Duplicate:
Unsigned and signed comparison
A riddle (in C)

#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
   int d = -1;
   if (d < TOTAL_ELEMENTS)
      printf("of course -1 is less than %d",TOTAL_ELEMENTS);
   else
      printf("how on earth");
   return 0;
}

answer is:::Output of the above program is : how on earth

Community
  • 1
  • 1
aditya
  • 11
  • 1
  • See also: http://stackoverflow.com/questions/950051/confused-about-c-macro-expansion-and-integer-arithmetic – Mat Jul 01 '12 at 17:16

2 Answers2

3

When you perform mixed signed vs. unsigned comparison (where signed type is not larger than unsigned one), the comparison is performed in unsigned domain, i.e. the signed operand is implicitly converted to unsigned type.

In your case TOTAL_ELEMENTS has type size_t, which is unsigned. That means that your d is also implicitly converted to size_t type. So, your d < TOTAL_ELEMENTS is actually interpreted as (size_t) d < TOTAL_ELEMENTS or (size_t) -1 < TOTAL_ELEMENTS.

(size_t) -1 is an extremely large positive value. It is actually the largest possible value of type size_t. Hence the result you get.

In your case you apparently want a signed comparison. For that you have to explicitly convert the unsigned value to signed type (paying close attention not to cause overflow). For example, this will work "as expected"

if (d < (int) TOTAL_ELEMENTS)
  ...
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
2

This is because sizeof_t is mapped to an unsigned long type, so -1 becomes 0xFFFFFFFFFFFFFFFF, a rather large positive integer. Try this:

#include<stdio.h>
#define TOTAL_ELEMENTS(a) ((int)(sizeof((a))/sizeof(*(a))))
int array[] = {23,34,12,17,204,99,16};
int main() {
    int d = -1;
    if (d < TOTAL_ELEMENTS(array)) {
        printf("of course -1 is less than %d",TOTAL_ELEMENTS(array));
    } else {
        printf("how on earth");
    }
    return 0;
}

Note how I re-wrote your macro to reference array as its parameter, and added a cast to int to ensure that comparing to -1 would bring an expected result.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523