编译器是否允许像Intel C ++编译器一样去除无限循环

以下测试代码可以在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 herern");}
};

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 ++的情况)。 据我所知,在这个问题上一直没有达成共识 - 聪明和知识渊博的人已经采取双方。


这听起来像一个错误。 这是一个(非常狂野)猜测可能导致它的原因...

内联后,它看到:

while (q.m_first == q.m_last) /* do nothing */ ;
do_something();

以及任何do nothing repeatedly ; do something序列do nothing repeatedly ; do something do nothing repeatedly ; do something可以翻译成简单的“做点什么”。 如果重复的部分是无穷无尽的(如在这种情况下),这会下降。 但也许他们不会测试他们编译的故意有无穷循环的例子;-)。


任何你构建和运行的实际代码在while(q.isEmpty())之后缺少分号的while(q.isEmpty()) ? 这肯定会导致下一行被无限调用。

链接地址: http://www.djcxy.com/p/30709.html

上一篇: Are compilers allowed to remove infinite loops like Intel C++ Compiler with

下一篇: Algorithm to find best strategy for placing blocks