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.

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:

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:

            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. The loop must terminate eventually (it may take quite a long time if the initial value of CurrentOvserverPathPointIndex is small compared to PathSize, though).

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.

More importantly, how many elements are there in 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归因
不隶属于 StackOverflow
scroll top