Consider this C program
#include <stdio.h>
#define TOTAL_ELEMENTS (sizeof(arr))/sizeof(arr[0])
int arr[] = {23, 34, 12, 17, 204, 99, 16};
int main() {
int d;
printf("%zu\n", TOTAL_ELEMENTS);
for (d = -1; d <= (TOTAL_ELEMENTS - 2); d++) {
printf("%d ", arr[d + 1]);
}
return 0;
}
compilers are giving output as 7
according to my dry run and reasoning output should be
7
23 34 12 17 204 99 16
Now in order to see what is going wrong I applied some Variation consider this code
#include <stdio.h>
#define TOTAL_ELEMENTS (sizeof(arr))/sizeof(arr[0])
int arr[] = {23, 34, 12, 17, 204, 99, 16};
int main() {
int d;
printf("%zu\n", TOTAL_ELEMENTS);
for (d = -1; d <=(int) ((TOTAL_ELEMENTS) - 2); d++) {
printf("%d ", arr[d + 1]);
}
return 0;
}
Notice that the only change I done is introducing type casting with int, and now it's giving expected results.
Now as much as I know when we compare in C program it can do conversion to bigger data-type right, so suppose TOTAL_ELEMENT even has bigger type like long then d should be converted to long and program should run fine but that is not happening. What points I am missing here?
In the comparison d <= (TOTAL_ELEMENTS - 2)
the rank of d
is lower than the rank of (TOTAL_ELEMENTS - 2)
as int
has lower precision than size_t
on your platform per 6.3.1.1:
The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
The compiler will cast int d = -1
to size_t
which yield a very large number (SIZE_MAX
from stdint.h) so the loop condition is false and the body of the loop is never executed.
size_t d
which type matches the type of your upper bound.()
the right hand side of the macro and each macro argument to avoid surprises.d
in the for
-loop.%zu
for size_t
.{}
around the loop body if thers is more than 1 statement, and return 0
is default so I left both out.#include <stdio.h>
#define TOTAL_ELEMENTS (sizeof (arr) / sizeof *(arr))
int main() {
int arr[] = {23, 34, 12, 17, 204, 99, 16};
printf("%zu\n", TOTAL_ELEMENTS);
for (size_t d = 0; d < TOTAL_ELEMENTS; d++)
printf("%d ", arr[d]);
}
and you get the expected output:
7
23 34 12 17 204 99 16