aleena george
aleena george

Reputation: 3

Why is the expected output not displayed

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

Answers (2)

Vlad from Moscow
Vlad from Moscow

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

ikegami
ikegami

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

Related Questions