'而'使用优化(GCC)时,语句的工作方式不同

时间:2014-12-15 15:51:29

标签: c gcc optimization

我遇到这样一段代码的问题:

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

我在GCC中有-O3(最优化)选项。在这种情况下,代码以一种奇怪的不可预测的方式工作。 当我有-O0(无优化)选项时,它可以正常工作。

如何强制使用-O3选项的编译器不优化while(...)行? 我尝试在里面使用volatile,但没有成功。我希望启用-O3选项,但要使代码正常运行。

修改

好的,这是完整的示例代码。可能是我的错,但我不知道问题是什么。

#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;
}

使用-O0和-O3运行它,您将看到差异。

EDIT2: 输出为-O0:

size of arr2: 2

k: 0
K: 1

使用-O3:

size of arr2: 2

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

对于任何k选项,我预计-O不应超过2个。

1 个答案:

答案 0 :(得分:3)

由于评论部分的噪音太大:

正如@Kevin所说,while (B && A)应该是while (A && B),因为A正在检查边界,并且语句从左到右执行直到错误。因此,B将在数组索引k超出范围之前调用未定义的行为,在达到A之前评估为false并停止循环。