1

この条件にバグがあります:

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

2 番目の条件では、bool 型の関数パラメーターである「dontRotate」の値を eax に移動し、それと比較しているように見えますが、dontRotate はそのコードの近くでは使用されていません。

これが少し小さなデータかもしれないことは理解していますが、個人的には明らかなコンパイラ エラーのように思えます。しかし悲しいことに、実際にバグレポートを作成するのに十分な自己完結型の問題にそれを抽出する方法がわかりません。

編集:実際の減速ではなく、タイプ:

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

編集2:

while の最後に debug print ステートメントを追加すると、これは生成されるアセンブリであり、もはやバグを表現していません。

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

2 に答える 2

1

ここ:

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

が変更され、 と の両方が同じサイズの符号付き整数である (そして、整数昇格の問題を除外するのに十分小さい) ループ内の唯一のポイント (min本当に厄介なことをしない限り) であるため、残りの浮動小数点のいじりは無関係です。ループは最終的に終了する必要があります ( の初期値が に比べて小さい場合は、かなり長い時間がかかる場合があります)。CurrentObserverPathPointIndexCurrentObserverPathPointIndexPathSizePathSizeCurrentOvserverPathPointIndexPathSize

これにより、1 つの結論しか得られません。コンパイラが (決して) 終了しないコードを生成する場合、コンパイラは間違っています。

于 2012-02-22T00:53:35.553 に答える
0

PathSizeはループ内で変化しないように見えるため、コンパイラはPathSize - 1ループする前に計算し、偶然にも と同じメモリ位置を使用できdontRotateます。

さらに重要なことは、 には要素がいくつあるCurrentObserverPath->pathPointsか?

ループ条件には次のテストが含まれます。

CurrentObserverPathPointIndex < (PathSize - 1)

ループ内には次の割り当てがあります。

CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1;

このさらにインクリメントされた添え字が続きます。

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

ランダムな未定義の動作が動作しているように見えたために、コードがデバッグ モードで動作しているように見えたのではないでしょうか?

于 2012-02-22T00:30:05.880 に答える