# 在'gcc -O2'上优化了函数无限循环

``void fn(void) { /* write something after this comment so that the program output is 10 */ /* write something before this comment */ } int main() { int i = 5; fn(); printf("%d\n", i); return 0; }` `

` `void fn(void) { /* write something after this comment so that the program output is 10 */ int a[1] = {0}; int j = 0; while(a[j] != 5) ++j; /* Search stack until you find 5 */ a[j] = 10; /* Overwrite it with 10 */ /* write something before this comment */ }` `

• 如果`i``j`更改为`volatile` ，程序行为保持不变。
• 如果数组`a`被制成`volatile` ，程序不会受到无限循环。
• 此外，如果我申请以下补丁
` `- int a[1] = {0}; + int aa[1] = {0}; + int *a = aa;` `

` `;; Function fn (fn) (executed once) Removing basic block 3 fn () { <bb 2>: <bb 3>: goto <bb 3>; } ;; Function main (main) (executed once) main () { <bb 2>: fn (); } Invalid sum of incoming frequencies 0, should be 10000` `

` `L2: jmp .L2` `

` `fn: .L2: jmp .L2` `

• a的所有元素都初始化为零
• `a`在循环之前或之内从不修改
• 所以`a[j] != 5`永远是真的 – >无限循环
• 由于无限， `a[j] = 10;` 是无法达到的，所以可以优化，所以可以`a``j`因为他们不再需要确定循环条件。

` `int d[16];` `

` `for (dd=d[k=0]; k<16; dd=d[++k])` `

C11在第`6.8.5`迭代语句中增加了一些说明，在本答案中有更详细的介绍。

1. 数组`a`在testing之前不会改变。
2. 数组`a`不包含`5`

` `void fn(void) { int a[1] = {0}; int j = 0; while(true) ++j; a[j] = 10; }` `

1. while循环之后的所有代码都是死代码（unreachable）。
2. `j`是书面的，但从来没有读过。 所以我们可以摆脱它。
3. `a`永远不会被读取。

` `void fn(void) { int a[1] = {0}; while(true); }` `

` `void fn(void) { while(true); }` `

### 现在，未经优化的代码：

1. `volatile`

2. 只包含`0`

3. 永远不会被写入

` `void fn(void) { /* write something after this comment so that the program output is 10 */ printf("10\n"); /* Output 10 */ while(1); /* Endless loop, function won't return, i won't be output */ /* write something before this comment */ }` `

` `void fn(void) { /* write something after this comment so that the program output is 10 */ printf("10\n"); /* Output 10 */ exit(0); /* Exit gracefully */ /* write something before this comment */ }` `