4

In this program the TOTAL_ELEMENTS calculates properly when not used in for loop. And the first printf prints properly. But why the 2nd printf is not working even if the condition in the loop is true. TOTAL_ELEMENTS returns 7. And -1<7-2 i.e -1<5is true. So what is wrong here?

#include<stdio.h>

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};

int main()
{
int d;
printf("Total= %d\n", TOTAL_ELEMENTS);
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Pankaj Mahato
  • 1,051
  • 5
  • 14
  • 26

3 Answers3

8

The problem is that sizeof returns an unsigned value. Therefore, the entire expression

TOTAL_ELEMENTS-2

is considered unsigned. The next thing that happens is that the comparison d <= (TOTAL_ELEMENTS-2) is considered an unsigned comparison. However, -1 in unsigned representation is the largest possible value, so <= is evaluated as false from the first iteration.

You can force a signed comparison by adding an explicit cast:

for(d=-1;d <= (int)((TOTAL_ELEMENTS)-2);d++)

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I thought that sizeof is returning a signed integer. – Pankaj Mahato Dec 21 '14 at 15:38
  • the sizeof can be considered as an unsigned long !!@PankajMahato – user12448 Dec 21 '14 at 15:45
  • @user12448 You can only say that for some platforms. `sizeof expr` and `sizeof(type)` results in a value of type `size_t`. `size_t` is actually a `typedef` for an unsigned type, and it is declared in a few header files. On my 64-bit Windows machine, `size_t` is 64-bit while `unsigned long` is 32-bit. Assuming they are the same can lead to problems. –  Dec 21 '14 at 17:11
  • For the `long int` it actually depends on the architecture ! in 64bit architecture it is 64 bit and in 32 bits architecture it is 32 bit !! – user12448 Dec 21 '14 at 17:28
0

your new code should be:

#include<stdio.h>

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};

int main()
{
 int d;
 printf("Total= %d\n", TOTAL_ELEMENTS);
 for(d=-1;d <= ((int)TOTAL_ELEMENTS-2);d++)
 {
   printf("%d\n",array[d+1]);
  }
 return 0;
  }

you need to cast the

TOTAL_ELEMENT to integer before doing a operation on that. it is not a variable.

Sumit Singh
  • 182
  • 3
  • 14
-3

TOTAL_ELEMENTS is a constant, you can't use as a variable.

vaultah
  • 44,105
  • 12
  • 114
  • 143
Juan Solo
  • 359
  • 1
  • 5
  • 17