cyclone125
cyclone125

Reputation: 336

'while' statement works differently when using optimization (GCC)

I have a problem with such a piece of code:

uint8_t var1, var2, var3, var4, var5[];
...
while ( ((var1 & var2) != var3) && (var4 < (sizeof(var5)/sizeof(var5[0]))) ){
... do something
}

I have an -O3 (Optimize most) option in GCC. In this case the code works in some strange unpredictable way. When I have an -O0 (None optimization) option, it works just fine.

How to force a compiler with -O3 option not to optimize just while(...) line? I tried to use volatile inside, but with no success. I want to have -O3 option on, but make the code working correctly.

EDIT:

Ok, this is the complete example code. May be it's my fault, but I don't see what the problem is.

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>


struct st{
    uint8_t     var1;
    uint8_t     var2;
};


int main(void) {

    uint8_t         k = 0;

    uint8_t         arr1[4] = {0, 0b11000000, 0b10000000, 0};

    const struct st arr2[] = {

            {0b11000000, 0b11000000},
            {0b10000000, 0b11000000}
    };

    printf("size of arr2: %d \n\n",sizeof(arr2)/sizeof(arr2[0]));

    while ( ((arr1[k] & arr2[k].var2) != arr2[k].var1) && (k < (sizeof(arr2)/sizeof(arr2[0]))) ){
        printf("k: %d \n",k);
        k++;
    }



    return 0;
}

Run it with -O0 and -O3 and you will see the difference.

EDIT2: The output with -O0:

size of arr2: 2

k: 0
K: 1

With -O3:

size of arr2: 2

k: 0
K: 1
k: 2
K: 3

I expect k should not be more than 2 with any -O option.

Upvotes: 0

Views: 107

Answers (1)

Jite
Jite

Reputation: 4368

Since it's too much noise in the comments section:

As @Kevin said, your while (B && A) should be while (A && B) since A is checking boundaries and the statement is being executed from left to right until false. Thus B will invoke undefined behaviour when array index k is out of bounds before A is reached to evaluate to false and stop the loop.

Upvotes: 3

Related Questions