以下测试代码在带有调试或发布的 VS 中以及在 GCC 中均正确执行。它也适用于带调试的 ICC,但在启用优化 (-O2
) 时不正确。
#include <cstdio>
class tClassA{
public:
int m_first, m_last;
tClassA() : m_first(0), m_last(0) {}
~tClassA() {}
bool isEmpty() const {return (m_first == m_last);}
void updateFirst() {m_first = m_first + 1;}
void updateLast() {m_last = m_last + 1;}
void doSomething() {printf("should not reach here\r\n");}
};
int main() {
tClassA q;
while(true) {
while(q.isEmpty()) ;
q.doSomething();
}
return 1;
}
它应该在 while(q.isEmpty())
处停止。但是,当在 ICC(发行版)下启用 -O2
时,它会开始无限地“做某事”。
由于这是单线程程序并且 isEmpty()
应该被评估为true
,我找不到 ICC 应该表现的理由这样?我错过了什么吗?
最佳答案
因为 while (q.isEmpty()) ;
循环不包含任何可能导致外部可见副作用的语句,所以整个循环被优化到不复存在。这是同样的原因:
for (int i = 0; i < 10; i++)
;
可以优化到不存在,只要 i
不是 volatile
(存储到 volatile
对象是“外部可见”的一部分“程序的效果)。
在C语言中,是否允许通过这种方式优化死循环实际上是一个突出的争论焦点(我不知道C++是什么情况)。据我所知,在这个问题上从来没有达成共识——聪明人和知识渊博的人都采取了双方。
关于c++ - 是否允许编译器像带有 -O2 的英特尔 C++ 编译器那样删除无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3527829/