2012-02-22 110 views
1

我有这个条件了一个错误:这是Visual Studio 2010中的编译器错误吗?

while(CurrentObserverPathPointDisplacement > lengthToNextPoint && CurrentObserverPathPointIndex < (PathSize - 1)) 
{ 
    CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1; 
    CurrentObserverPathPointDisplacement -= lengthToNextPoint; 
    lengthToNextPoint = (CurrentObserverPath->pathPoints[min((PathSize - 1),CurrentObserverPathPointIndex + 1)] - CurrentObserverPath->pathPoints[CurrentObserverPathPointIndex]).length(); 
} 

这似乎陷入一个死循环,而在发布模式。作品interstingly在调试模式罚款,或者更多的时候,我把一个调试打印的最后一行

OutputInDebug("Here"); 

这里是条件本身生成的汇编:

  while(CurrentObserverPathPointDisplacement > lengthToNextPoint && CurrentObserverPathPointIndex < (PathSize - 1)) 
00F074CF fcom  qword ptr [dist] 
00F074D2 fnstsw  ax 
00F074D4 test  ah,5 
00F074D7 jp   ModelViewData::moveCameraAndCenterOnXYPlaneForwardBackward+27Eh (0F0753Eh) 
00F074D9 mov   eax,dword ptr [dontRotate] 
00F074DC cmp   eax,ebx 
00F074DE jge   ModelViewData::moveCameraAndCenterOnXYPlaneForwardBackward+27Eh (0F0753Eh) 
      { 

你可以看到,对于第二条件,它似乎将'bont类型的函数参数'dontRotate'的值移动到eax中,然后与它进行比较,但dontRotate在该代码位置附近没有使用。

我明白,这可能是一些小数据,但它似乎是个人明显的编译器错误。但令人遗憾的是,我不确定如何将它提炼成一个足以解决问题的实际产生错误报告的问题。

编辑: 不是实际的减速,但类型:

double CurrentObserverPathPointDisplacement; 
double lengthToNextPoint; 
int CurrentObserverPathPointIndex; 
int PathSize; 
vector<vector3<double>> CurrentObserverPath::pathPoints; 

EDIT2:

有一次,我在调试print语句,而末尾添加,这是得到大会产生,不再表达错误:

  while(CurrentObserverPathPointDisplacement > lengthToNextPoint && CurrentObserverPathPointIndex < (PathSize - 1)) 
00B1751E fcom  qword ptr [esi+208h] 
00B17524 fnstsw  ax 
00B17526 test  ah,5 
00B17529 jp   ModelViewData::moveCameraAndCenterOnXYPlaneForwardBackward+2D6h (0B175A6h) 
00B1752B mov   eax,dword ptr [esi+200h] 
00B17531 cmp   eax,ebx 
00B17533 jge   ModelViewData::moveCameraAndCenterOnXYPlaneForwardBackward+2D6h (0B175A6h) 
      { 
+1

这看起来不像对应于任何代码的指令。 – wallyk 2012-02-22 00:17:59

+2

首先,您可能已经缩短了一些标识符。但是,要弄清楚发生了什么,查看涉及哪些类型将会很有帮助。 – bitmask 2012-02-22 00:20:10

+1

请包装那些过长的行。 – 2012-02-22 00:20:51

回答

1

这里:

while(/* foo */ && CurrentObserverPathPointIndex < (PathSize - 1)) 
{ 
    CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1; 

因为这是唯一的点(除非min做一些令人头痛)在CurrentObserverPathPointIndex改变循环,既CurrentObserverPathPointIndexPathSize都签署了相同大小的整数(和PathSize是小到足以排除整数提升问题),剩下的浮点摆动就无关紧要了。循环必须最终终止(如果CurrentOvserverPathPointIndex的初始值比PathSize小,则可能需要相当长的时间)。

这只允许一个结论;如果编译器生成的代码没有终止(永远),编译器是错误的。

+0

一个有趣的发展是,如果我将CurrentObserverPathPointIndex标记为volatile,则程序将按预期运行。我想这是最有价值的,看看我能否找到某种类型的复制来处理这个确切的错误。 – Arelius 2012-02-22 00:57:47

+0

@Arelius:要提交错误报告,无论如何这都会有所帮助(但是,我不知道MSVC错误报告如何工作,但我不认为它们与gcc的差别很大)。 – bitmask 2012-02-22 01:00:14

+0

你可能意思是“如果初始值......太负面”? – 2012-02-22 01:08:37

0

它看起来像PathSize在循环不会改变,所以编译器可以在循环之前计算PathSize - 1,并巧妙地使用与dontRotate相同的内存位置,无论如何。

更重要的是,CurrentObserverPath->pathPoints中有几个元素?

你的循环条件包括这个测试:

CurrentObserverPathPointIndex < (PathSize - 1) 

里面你的循环是这样分配:

CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1; 

随后这进一步递增的下标:

[min((PathSize - 1),CurrentObserverPathPointIndex + 1)] 

也许你的代码出现在调试模式下工作,因为随机未定义的行为似乎工作?

+0

实际上查看变量值时,ebx正在获取PathSize-1的值,并且寄存器只是保持不变。 CurrentObserverPath-> pathPoints中有PathSize点。 – Arelius 2012-02-22 00:32:33

+2

@Arelius:我发现当问题更可能出现在你的代码的语义中时(你没有正确地向我们展示),你固定在生成的程序集上,这是奇怪的... – ildjarn 2012-02-22 00:37:20

+0

@ildjarn could you澄清你想看到哪种语义,我实际上找不到比我的整个程序还小的再现案例。 但我的注意事项存在,因为生成的代码是如此明显错误的事实。为了帮助用生成的代码表达我对问题的信心,我编辑了现有的问题,以便在添加调试语句时包含生成的代码。 – Arelius 2012-02-22 00:45:49