简体   繁体   English

这是Visual Studio 2010中的编译器错误吗?

[英]Is this a compiler error in Visual Studio 2010?

I have a bug in this conditional: 我在这种情况下有一个错误:

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

It seems to get stuck in an infinite loop while in Release mode. 在“释放”模式下,它似乎陷入了无限循环。 Works fine in debug mode, or more interstingly when I put a debug print on the last line 在调试模式下工作正常,或者在最后一行放置调试打印内容时更有趣

OutputInDebug("Here");

Here is the generated assembly for the conditional itself: 这是条件本身生成的程序集:

            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)  
            {

You can see that for the second condition, it seems to move the value of 'dontRotate', a function parameter of type bool, into eax, and then compare against it, yet dontRotate is used nowhere near that bit of code. 您可以看到,在第二种情况下,似乎将类型为bool的函数参数'dontRotate'的值移到了eax中,然后与之进行比较,但是dontRotate在该代码段附近没有使用。

I understand that this may be a bit little data, but it seems like an obvious compiler error personally. 我知道这可能是一些数据,但是个人看来似乎是一个明显的编译器错误。 But sadly, i'm not sure how to distill it down to a self contained enough problem to actually produce a bug report. 但是可悲的是,我不确定如何将其提炼成一个足以解决实际问题的报告。

Edit: Not the actual decelerations, but the types: 编辑:不是实际的减速度,而是类型:

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

Edit2: 编辑2:

Once I add in the debug print statement to the end of the while, this is the assembly that gets generated, which no longer expresses the bug: 一旦我将debug 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)  
            {

Here: 这里:

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

Since this is the only point (unless min does something really nasty) in the loop where CurrentObserverPathPointIndex is changed and both CurrentObserverPathPointIndex and PathSize are signed integers of the same size (and PathSize is small enough to rule out integer promotion issues), the remaining floating point fiddling is irrelevant. 由于这是更改CurrentObserverPathPointIndex的循环中唯一的点(除非min确实做得很讨厌),并且CurrentObserverPathPointIndexPathSize都是相同大小的有符号整数(并且PathSize小得可以排除整数提升问题),因此其余的浮动点摆弄是无关紧要的。 The loop must terminate eventually (it may take quite a long time if the initial value of CurrentOvserverPathPointIndex is small compared to PathSize , though). 循环必须最终终止(但是,如果CurrentOvserverPathPointIndex的初始值CurrentOvserverPathPointIndex PathSize ,则可能要花很长时间)。

This allows only one conclusion; 这仅得出一个结论。 If the compiler generates code that does not terminate (ever), the compiler is wrong. 如果编译器生成的代码永远不会终止,则说明编译器是错误的。

It looks like PathSize doesn't change in the loop, so the compiler can compute PathSize - 1 before looping and coincidentally use the same memory location as dontRotate , whatever that is. 看起来PathSize在循环中没有变化,因此编译器可以在循环之前计算PathSize - 1 ,并且无论使用dontRotate ,巧合地使用与dontRotate相同的内存位置。

More importantly, how many elements are there in CurrentObserverPath->pathPoints ? 更重要的是, CurrentObserverPath->pathPoints中有多少个元素?

Your loop condition includes this test: 您的循环条件包括此测试:

CurrentObserverPathPointIndex < (PathSize - 1)

Inside your loop is this assignment: 在您的循环中是此分配:

CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1;

followed by this further incremented subscript: 接下来是这个进一步增加的下标:

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

Maybe your code appeared to work in debug mode because random undefined behaviour appeared to work? 也许您的代码似乎可以在调试模式下工作,因为随机的未定义行为似乎可以工作吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM