¿Es este un error de compilador en Visual Studio 2010?
-
28-10-2019 - |
Pregunta
Tengo un error en este condicional:
while(CurrentObserverPathPointDisplacement > lengthToNextPoint && CurrentObserverPathPointIndex < (PathSize - 1) )
{
CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1;
CurrentObserverPathPointDisplacement -= lengthToNextPoint;
lengthToNextPoint = (CurrentObserverPath->pathPoints[min((PathSize - 1),CurrentObserverPathPointIndex + 1)] - CurrentObserverPath->pathPoints[CurrentObserverPathPointIndex]).length();
}
Parece atascarse en un bucle infinito mientras está en modo de liberación. Funciona bien en el modo de depuración, o más intervinidamente cuando pongo una impresión de depuración en la última línea
OutputInDebug("Here");
Aquí está el ensamblaje generado para el condicional en sí:
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)
{
Puede ver que para la segunda condición, parece mover el valor de 'dontrotate', un parámetro de función de tipo bool, a EAX, y luego compararse con él, pero dontrotate no se usa en ningún lugar cerca de ese bit de código.
Entiendo que esto puede ser un poco de pequeño datos, pero parece un error de compilador obvio personalmente. Pero lamentablemente, no estoy seguro de cómo destilarlo a un problema suficiente para producir un informe de errores.
Editar: no las desaceleraciones reales, sino los tipos:
double CurrentObserverPathPointDisplacement;
double lengthToNextPoint;
int CurrentObserverPathPointIndex;
int PathSize;
vector<vector3<double>> CurrentObserverPath::pathPoints;
Edit2:
Una vez que agrego la declaración de impresión de depuración al final del tiempo, este es el ensamblaje que se genera, que ya no expresa el error:
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)
{
Solución
Aquí:
while(/* foo */ && CurrentObserverPathPointIndex < (PathSize - 1) )
{
CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1;
Dado que este es el único punto (a menos que min
hace algo realmente desagradable) en el bucle donde CurrentObserverPathPointIndex
se cambia y ambos CurrentObserverPathPointIndex
y PathSize
son enteros firmados del mismo tamaño (y PathSize
es lo suficientemente pequeño como para descartar problemas de promoción de enteros), el violín flotante restante es irrelevante. El bucle debe terminar eventualmente (puede llevar bastante tiempo si el valor inicial de CurrentOvserverPathPointIndex
es pequeño en comparación con PathSize
, aunque).
Esto permite solo una conclusión; Si el compilador genera código que no termina (nunca), el compilador está mal.
Otros consejos
Parece que PathSize
no cambia en el bucle, por lo que el compilador puede calcular PathSize - 1
antes de bucle y coincidiendo coincidiendo la misma ubicación de memoria que dontRotate
, sea lo que sea.
Más importante aún, ¿cuántos elementos hay en CurrentObserverPath->pathPoints
?
Su condición de bucle incluye esta prueba:
CurrentObserverPathPointIndex < (PathSize - 1)
Dentro de su bucle está esta tarea:
CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1;
seguido de este subíndice incrementado adicional:
[min((PathSize - 1),CurrentObserverPathPointIndex + 1)]
¿Quizás su código parecía funcionar en modo de depuración porque el comportamiento indefinido aleatorio parecía funcionar?