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

Is this a compiler error in Visual Studio 2010?

本文关键字:编译器 错误 Visual Studio 2010 这是      更新时间:2023-10-16

我在这个条件中有一个错误:

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

在释放模式下,它似乎陷入了一个无限循环。在调试模式下运行良好,或者当我在最后一行上打印调试打印时更有趣

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

您可以看到,对于第二个条件,它似乎将bool类型的函数参数"dontRotate"的值移动到eax中,然后与之进行比较,但dontRotae的使用与代码的使用相去甚远。

我知道这可能是一个有点小的数据,但就我个人而言,这似乎是一个明显的编译器错误。但遗憾的是,我不知道如何将其提炼成一个足够独立的问题来实际生成错误报告。

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

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

第2版:

一旦我在这段时间的末尾添加调试打印语句,这就是生成的程序集,它不再表达错误:

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

此处:

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

由于这是循环中CurrentObserverPathPointIndex发生变化并且CurrentObserverPathPointIndexPathSize都是相同大小的有符号整数(并且PathSize足够小,可以排除整数提升问题)的唯一点(除非min做了一些非常恶劣的事情),因此剩余的浮点篡改是不相关的。循环最终必须终止(不过,如果CurrentOvserverPathPointIndex的初始值与PathSize相比较小,则可能需要相当长的时间)。

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

看起来PathSize在循环中没有改变,所以编译器可以在循环之前计算PathSize - 1,并巧合地使用与dontRotate相同的内存位置,不管是什么。

更重要的是,CurrentObserverPath->pathPoints中有多少元素?

您的环路条件包括此测试:

CurrentObserverPathPointIndex < (PathSize - 1)

在你的循环中是这样的任务:

CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1;

然后是这个进一步增加的下标:

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

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