Это ошибка компилятора в Visual Studio 2010? - PullRequest
1 голос
/ 22 февраля 2012

У меня есть ошибка в этом условии:

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

Кажется, что он застрял в бесконечном цикле в режиме Release. Прекрасно работает в режиме отладки или, что еще интереснее, когда я помещаю отладочную печать в последнюю строку

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

Вы можете видеть, что для второго условия, похоже, что значение dontRotate, параметр функции типа bool, перемещается в eax, а затем сравнивается с ним, однако dontRotate не используется нигде рядом с этим битом кода.

Я понимаю, что это может быть немного мало данных, но лично это кажется очевидной ошибкой компилятора. Но, к сожалению, я не уверен, как отогнать это до самодостаточной проблемы, чтобы на самом деле создать отчет об ошибке.

Edit: Не фактические замедления, а типы:

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

Редактировать2:

Как только я добавляю оператор печати отладки до конца времени, генерируется сборка, которая больше не выражает ошибку:

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

Ответы [ 2 ]

1 голос
/ 22 февраля 2012

Здесь:

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

Поскольку это единственная точка (если min не делает что-то действительно неприятное) в цикле, где CurrentObserverPathPointIndex изменяется, и оба значения CurrentObserverPathPointIndex и PathSize являются знаковыми целыми числами одного размера (а PathSize - это достаточно мал, чтобы исключить проблемы целочисленного продвижения), оставшаяся суета с плавающей точкой не имеет значения. Цикл должен в конечном итоге завершиться (может потребоваться довольно много времени, если начальное значение CurrentOvserverPathPointIndex мало по сравнению с PathSize, однако).

Это позволяет сделать только один вывод; Если компилятор генерирует код, который не завершается (никогда), компилятор неверен.

0 голосов
/ 22 февраля 2012

Похоже, PathSize не изменяется в цикле, поэтому компилятор может вычислить PathSize - 1 перед циклом и по совпадению использовать ту же ячейку памяти, что и dontRotate, что бы это ни было.

Подробнееважно, сколько элементов содержится в CurrentObserverPath->pathPoints?

Ваше условие цикла включает в себя этот тест:

CurrentObserverPathPointIndex < (PathSize - 1)

Внутри вашего цикла есть это назначение:

CurrentObserverPathPointIndex = CurrentObserverPathPointIndex + 1;

с последующим дополнительным увеличенным индексом:

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

Может быть, ваш код работает в режиме отладки, потому что работает случайное неопределенное поведение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...