Reputation: 3
why there is no output for this?
#include <stdio.h>
int main() {
int i;
int array[4] = {10, 25, 36, 42};
// int size=sizeof(array) / sizeof(int);
for (i = -1; i < sizeof(array) / sizeof(int); i++) {
printf("%d ", array[i+1]);
}
return 0;
}
Expected output is 10 25 36 42
Upvotes: -3
Views: 105
Reputation: 311088
Within the conditional expression of the for loop
for (i = -1; i < sizeof(array) / sizeof(int); i++) {
the variable i
having the signed type int
is implicitly converted to the unsigned type size_t
due to the usual arithmetic conversions because the expression sizeof(array) / sizeof(int)
has the unsigned integer type size_t
and the rank of the type size_t
(that is usually an alias for the type unsigned long
) is greater than the rank of the type int
.
As a result the expression ( size_t )-1
(the variable i
is set initially to -1
) that is the left operand of the condition
i < sizeof(array) / sizeof(int)
becomes a very big unsigned value due to propagating the sign bit.
Try for example this call of printf
printf( "( size_t )-1 = %zu\n", ( size_t )-1 );
So the condition of the if statement evaluates to logical false.
You could write for example
for ( i = -1; i < ( int )( sizeof(array) / sizeof(int) ); i++) {
to get the expected result - to execute the for loop.
Though in any case the loop will invoke undefined behavior because when i
will be equal to ( int )( sizeof(array) / sizeof(int) ) - 1
the expression array[i+1]
will try to access memory beyond the defined array.
It will be much better and correct to write
for ( size_t i = 0; i < sizeof(array) / sizeof(*array); i++) {
printf("%d ", array[i]);
}
Upvotes: 3
Reputation: 386541
Comparing signed and unsigned values can lead to surprising behaviour. You are effectively doing (size_t)i < sizeof(array) / sizeof(int)
, and (size_t)-1
is a huge number.
In this case, there's no reason to start with i = -1
; this can be done correctly and more simply with i = 0
, which avoids the problem at hand. (You attempted to loop once too many times anyway, and starting with i = 0
also fixed that.)
ALWAYS enable your compiler's warnings. With gcc or clang, I use -Wall -Wextra -pedantic
. It would have caught this.
Upvotes: 2