Question

J'ai un bug dans ce conditionnel:

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

Il semble rester coincé dans une boucle infinie en mode libération. Fonctionne bien en mode débogage, ou plus interstoutant lorsque je mets une impression de débogage sur la dernière ligne

OutputInDebug("Here");

Voici l'assemblage généré pour le conditionnel lui-même:

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

Vous pouvez voir que pour la deuxième condition, il semble déplacer la valeur de «dontrotate», un paramètre de fonction de type bool, dans EAX, puis comparer avec lui, mais Dontrotate est utilisé nulle part près de ce morceau de code.

Je comprends que cela peut être un peu peu de données, mais cela semble être une erreur évidente du compilateur personnellement. Mais malheureusement, je ne sais pas comment le distiller à un problème autonome pour produire un rapport de bogue.

Edit: pas les décélérations réelles, mais les types:

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

Edit2:

Une fois que j'ai ajouté l'instruction d'impression de débogage à la fin du temps, c'est l'assemblée qui est générée, qui n'exprime plus le bogue:

            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)  
            {
Était-ce utile?

La solution

Ici:

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

Puisque c'est le seul point (sauf si min fait quelque chose de vraiment méchant) dans la boucle où CurrentObserverPathPointIndex est changé et les deux CurrentObserverPathPointIndex et PathSize sont signés entiers de la même taille (et PathSize est suffisamment petit pour exclure les problèmes de promotion entière), le point de triage flottant restant n'est pas pertinent. La boucle doit éventuellement se terminer (cela peut prendre beaucoup de temps si la valeur initiale de CurrentOvserverPathPointIndex est petit par rapport à PathSize, pourtant).

Cela ne permet qu'une seule conclusion; Si le compilateur génère du code qui ne se termine pas (jamais), le compilateur est faux.

Autres conseils

On dirait PathSize ne change pas dans la boucle, donc le compilateur peut calculer PathSize - 1 Avant de boucler et de coïncidrement utiliser le même emplacement de mémoire que dontRotate, Quoique ce soit.

Plus important encore, combien d'éléments y a-t-il CurrentObserverPath->pathPoints?

Votre condition de boucle comprend ce test:

CurrentObserverPathPointIndex < (PathSize - 1)

À l'intérieur de votre boucle se trouve cette affectation:

CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1;

suivi par cet indice supplémentaire incrémenté:

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

Peut-être que votre code semblait fonctionner en mode débogage parce que le comportement non défini aléatoire semblait fonctionner?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top