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?
>Solution :
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.
int d = -1 is cast 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.
Prefer the standard for-loop idiom. Then you can use size_t d which type matches the type of your upper bound. Avoid global variables. Remove unused variables. Minimize scope of variables; in this case by declaring d in the for-loop. Use the correct format string %zu for size_t. I also left out the optional {} and return 0.
#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