如果我尝试运行这样的循环:
int i;
for (i = 0; i < 1e9; i++)
{
1 + 1;
}
编译器完全优化它,甚至不运行它。但是如果我使int i
静态,那么它就会继续运行循环,即使我进行了更高的迭代。这是在Visual Studio 2013中,在发布模式下打开了优化。
答案 0 :(得分:2)
很明显,循环体是无操作的。循环的唯一影响是更改i
的值。当i
具有自动存储时,编译器可以证明在循环之后永远不会读取i
的值。因此,整个循环没有效果,可以丢弃。
但是,当i
为static
时,其生命周期超出了函数的单次调用。因此,i
的值是副作用,并且不能丢弃循环。
你可能会争辩说编译器可以深入挖掘并证明即使是static i
也永远不会被读取,但这是一个更难以证明的事情。
答案 1 :(得分:1)
当我不是静态时,这整段代码不会影响程序的可观察状态。正如您所注意到的,编译器会优化循环。这称为死代码消除。
现在,当我是静态的时,VC ++编译器立即放弃而不是优化代码(大多数非平凡的优化都不会被使用,无论它们是否适用)。如果两个或多个线程同时调用该函数,那么大多数优化(包括死代码消除)可能会对程序状态造成可观察到的副作用,从而导致它们非法。
当然,在这种情况下,我们没有使用任何线程。但是VC ++不会分析代码(出于好的理由),所以,为了安全起见,它只是放弃了。
如果它确实分析了代码并发现只有一个线程正在调用该函数,那么它实际上能够通过用一个加法语句替换循环来优化它,如果我是静态的那样。