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.