2012-02-22 7 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(); 
} 

동안 릴리스 모드에서 무한 루프에 갇혀 얻을 것으로 보인다.

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

당신은 두 번째에 대한 것을 볼 수 있습니다 : 내가 마지막 줄 다음

OutputInDebug("Here"); 

에 디버그 프린트를 넣어 때 자체 조건에 대해 생성 된 어셈블리가 interstingly 디버그 모드에서 잘, 이상 작동 조건에서는 bool 유형의 함수 매개 변수 인 'dontRotate'의 값을 eax로 이동 한 다음 비교합니다. 그러나 dontRotate는 해당 비트 근처에서 사용되지 않습니다.

이 데이터는 조금 작을 수도 있지만 개인적으로 명백한 컴파일러 오류처럼 보입니다. 하지만 슬프게도, 실제로 버그 리포트를 생성하기에 충분한 문제가있는 것으로 분류하는 방법을 모르겠습니다.

편집 : 하지 실제 감속하지만, 유형 :

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

Edit2가 :

나는 동안의 끝에 디버그 인쇄 문에 추가하면, 이것은 얻는 조립입니다 더 이상 버그를 표현하는 생성되지 :

  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에 비해 작 으면 꽤 오랜 시간이 걸릴 수 있습니다).

이렇게하면 하나의 결론 만 허용됩니다. 컴파일러가 종료되지 않는 코드를 생성하면 컴파일러가 잘못됩니다.

+0

재미있는 개발은 CurrentObserverPathPointIndex를 휘발성으로 표시하면 프로그램이 예상대로 작동한다는 것입니다. 이 정확한 오류에 대한 재현을 찾을 수 있는지 알아 보는 것이 가장 중요하다고 생각합니다. – Arelius

+0

@Arelius : 버그 보고서를 제출하려면이 방법이 도움이 될 것입니다. 그러나 MSVC 버그 보고서의 작동 방식에 대한 단서가 없지만 gcc와 다른 점은 기대하지 않습니다. – bitmask

+0

아마 "초기 값이 너무 부정적이라면?" –

0

그것은 루프에서 변경되지 않습니다 PathSize처럼 보이는, 그래서 컴파일러 루핑하기 전에 PathSize - 1을 계산할 수 있으며 우연히 일치하는 메모리 위치는 dontRotate입니다.

더욱 중요한 것은 CurrentObserverPath->pathPoints에 몇 개의 요소가 있습니까?

CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1; 

이 더 증분 첨자 다음 : 루프 내부

CurrentObserverPathPointIndex < (PathSize - 1) 

이 과제입니다 :

귀하의 루프 조건이 테스트를 포함

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

아마 코드 등장 정의되지 않은 임의의 동작이 작동하기 때문에 디버그 모드에서 작동합니까? 여기

+0

실제로 변수 값을 보면 ebx는 PathSize - 1 값을 가져오고 레지스터는 그대로 유지됩니다. CurrentObserverPath-> pathPoints에 PathSize 포인트가 있습니다. – Arelius

+2

@Arelius : 문제가 코드의 의미에있을 확률이 높을 때 생성 된 어셈블리에 고정되어 있다는 것이 기이합니다. – ildjarn

+0

@ildjarn can you 어떤 시맨틱을보고 싶은지 명확히 해두 자면, 실제적으로 프로그램의 전체 크기보다 작은 재생산 사례를 찾을 수 없습니다. 그러나 생성 된 코드가 너무 분명하게 잘못되어 있기 때문에 문제가 발생합니다. 생성 된 코드의 문제점에 대한 자신감을 나타 내기 위해 디버그 문을 추가 할 때 생성 된 코드를 포함하도록 기존 질문을 편집했습니다. – Arelius