令人费解的编译器优化结果

时间:2015-04-17 05:41:29

标签: c++ optimization compiler-optimization

如果我尝试运行这样的循环:

int i;

for (i = 0; i < 1e9; i++)
{
    1 + 1;
}

编译器完全优化它,甚至不运行它。但是如果我使int i静态,那么它就会继续运行循环,即使我进行了更高的迭代。这是在Visual Studio 2013中,在发布模式下打开了优化。

2 个答案:

答案 0 :(得分:2)

很明显,循环体是无操作的。循环的唯一影响是更改i的值。当i具有自动存储时,编译器可以证明在循环之后永远不会读取i的值。因此,整个循环没有效果,可以丢弃。

但是,当istatic时,其生命周期超出了函数的单次调用。因此,i的值是副作用,并且不能丢弃循环。

你可能会争辩说编译器可以深入挖掘并证明即使是static i也永远不会被读取,但这是一个更难以证明的事情。

答案 1 :(得分:1)

当我不是静态时,这整段代码不会影响程序的可观察状态。正如您所注意到的,编译器会优化循环。这称为死代码消除。

现在,当我是静态的时,VC ++编译器立即放弃而不是优化代码(大多数非平凡的优化都不会被使用,无论它们是否适用)。如果两个或多个线程同时调用该函数,那么大多数优化(包括死代码消除)可能会对程序状态造成可观察到的副作用,从而导致它们非法。

当然,在这种情况下,我们没有使用任何线程。但是VC ++不会分析代码(出于好的理由),所以,为了安全起见,它只是放弃了。

如果它确实分析了代码并发现只有一个线程正在调用该函数,那么它实际上能够通过用一个加法语句替换循环来优化它,如果我是静态的那样。

相关问题