我有这段代码:
#includevoid 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; }
在使用优化off($ 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)如果我取消注释printf
do while循环内部.
显然,我不明白优化正在做什么,以及为什么它改变了我的程序的行为.我可以选择上述解决方案之一来让它运行,但我真的很想知道这里发生了什么.这对我来说太奇怪了.
(C++标签可能不合适,但我也看到使用g ++的相同行为)
正如评论中指出的,如果您调用未定义的行为,可能会发生这种情况.
在您的情况下,这是相关部分:
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]
.这是另外一个分配.