This is a result of the "usual arithmetic conversions".
From section 6.3.1.8 of the C standard:
If both operands have the same type, then no further conversion is
needed.
Otherwise, if both operands have signed integer types or both have
unsigned integer types, the operand with the type of lesser
integer conversion rank is converted to the type of the operand
with greater rank.
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.
Otherwise, if the type of the operand with signed integer type can
represent all of the values of the type of the operand with unsigned
integer type, then the operand with unsigned integer type is
converted to the type of the operand with signed integer type.
Otherwise, both operands are converted to the unsigned
integer type corresponding to the type of the operand with signed
integer type.
The sizeof
operator returns a size_t
, which is an unsigned value. So (sizeof(array) / sizeof(array[0])) - 2
is also unsigned.
Because you are comparing a signed and an unsigned value, the signed value is converted to unsigned. Converting -1 to unsigned results in the largest unsigned value, which results in the comparison being false.
If you cast the right hand side to int
, it will work as expected.
for(d=-1;d <= (int)(TOTAL_ELEMENTS-2);d++)
Output:
23
34
12
17
204
99
16
Or you could avoid the issue by normalizing how you index the array:
for (d = 0; d < TOTAL_ELEMENTS; d++) {
printf("%d\n", array[d]);
}