2012-02-22 12 views
1

私はこの条件にバグがありますこれはVisual Studio 2010のコンパイラエラーですか?

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

しばらくリリースモードで無限ループにはまり込むように思われます。デバッグモードでは正常に動作、または私は最後の行にデバッグプリントを入れて、よりinterstinglyたときにここで

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に移動して比較すると思われますが、dontRotateはそのコードの近くでは使用されません。

私はこれがちょっとしたデータではないことを理解していますが、個人的に明らかなコンパイラエラーのようです。しかし、悲しいことに、実際にバグレポートを作成するのに十分な問題を含んでいる自己にそれを引き出す方法がわかりません。

編集: は実際の減速が、型ではない:

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

EDIT2:私はしばらくの最後にデバッグ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) 
      { 
+1

これは、コードに対応する指示には見えません。 – wallyk

+2

まず、識別子を少し短くすることができました。しかし、何が起きているのかを理解するには、どのようなタイプが関係しているのかを知ることが役に立ちます。 – bitmask

+1

長すぎる行を折り返してください。 –

答えて

1

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

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

これにより、結論は1つのみです。コンパイラが(それまで)終了しないコードを生成すると、コンパイラは間違っています。

+0

興味深い開発は、私がCurrentObserverPathPointIndexをvolatileとしてマークすると、プログラムが期待どおりに動作することです。私はこの正確なエラーのために何らかの再現を見つけることができるかどうかを知ることが最も価値があると思います。 – Arelius

+0

@Arelius:バグレポートを提出するには、とにかく参考になります(ただし、MSVCのバグレポートの仕組みは分かりませんが、gccとはかなり異なるとは思われません)。 – bitmask

+0

あなたはおそらく "初期値が...あまりにも負である"という意味ですか? –

0

これは、ループ内で変更されませんPathSizeのように見えるので、コンパイラループの前にPathSize - 1を計算し、偶然にはdontRotateと同じメモリ位置を使用することができます。

さらに重要なことに、いくつの要素がCurrentObserverPath->pathPointsにありますか?

あなたのループ条件は、このテストが含まれています。あなたのループ内

CurrentObserverPathPointIndex < (PathSize - 1) 

この割り当てている:たぶんあなたのコードが登場

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

この更なるインクリメント添字が続く
CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1; 

ランダムな未定義のビヘイビアが動作するように見えるので、デバッグモードで動作しますか?ここで

+0

実際に変数の値を見ると、ebxはP​​athSize - 1の値を取得しており、レジスタは変更されません。 CurrentObserverPath-> pathPointsにPathSizeポイントがあります。 – Arelius

+2

@Arelius:問題がコードのセマンティクスにある可能性が高い場合(生成されたアセンブリに固定されていることは奇妙なことです)。 – ildjarn

+0

@ildjarnできますどのセマンティクスを見たいのかを明確にするために、実際に私のプログラム全体よりも小さい再生ケースを実際に見つけることはできません。 しかし、私の修正は、生成されたコードが非常に間違っているという事実のために存在します。生成されたコードの問題に対する私の自信を表明するために、私はdebug文を追加するときに生成されたコードを含む既存の質問を編集しました。 – Arelius

関連する問題