我有这段代码:
#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 ++的相同行为)
答案 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]
。这是另一个分配。