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)  
            {
¿Fue útil?

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?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top