在某些条件下非常奇怪的代码,包括优化

时间:2015-12-18 19:37:07

标签: c++ c gcc optimization

我有这段代码:

#include <stdio.h>     

void optimization_headache()    
{    
    int t = 11;    
    int l[1047] = {0};    
    int u_lu[23] = {0};    

    int u = 0;    

    l[0] = 0;    
    l[1] = 0;    

    do {    
        u++;    
        //printf("Incrementing u, now u is %d\n", u);     
        u_lu[u + 1] = u - l[u + 1];    
    } while ((u < t * 2) && (l[u + 1] <= t));    

    printf("u = %d, l[u] = %d, t = %d, u_lu[u] = %d\n", u, l[u], t, u_lu[u]);    
}    

int main()    
{    
    optimization_headache();    

    return 0;    
}

关闭优化($ gcc -Wall -Wextra -O0 main.c)后,代码编译,我得到以下输出:

u = 22, l[u] = 0, t = 11, u_lu[u] = 21

当我使用完全优化($ gcc -Wall -Wextra -O3 main.c)进行编译时,程序会挂起,而top表示它正在使用100%的CPU。它必须在do while循环中永远运行。

我可以通过完全优化来编译代码,并通过更改以下一项或全部内容来正确运行:

1)如果我评论l[0] = 0; l[1] = 0;

2)如果我改为u volatile int

3)如果我取消注释do while循环中的printf

很明显,我不明白优化正在做什么,以及为什么它改变了我的程序的行为。我可以选择上述解决方案之一来让它运行,但我真的很想知道这里发生了什么。这对我来说太奇怪了。

(C ++标签可能不合适,但我也看到了使用g ++的相同行为)

1 个答案:

答案 0 :(得分:7)

正如评论中所指出的,如果你调用undefined behavior,可能会发生这种情况。

在您的情况下,这是相关部分:

int t = 11;    
int u_lu[23] = {0};    

do {    
    u++;    
    u_lu[u + 1] = u - l[u + 1];    
} while ((u < t * 2) /*...*/);    

循环在u小于22时运行,因此它可以变为21.但在循环内,您将u递增两次并写入u_lu[23]。这是另一个分配。