В приаттаченом проекте на билдере тупа студенческая прога. Не в этом суть. Тут в коде таится интересная ошибка. Парились часа 3 так и не нашли. Вопрос решила только обертка в критическую секцию. Код (Text): float tek = fabs(Ft); float pred = fabs(tan(i-Ht)); float rez = tek-pred; CRITICAL_SECTION CritSec; InitializeCriticalSection(&CritSec); //EnterCriticalSection(&CritSec); float y = fabs(rez); if ( y > 100) //тут даже при y<1 после проверки выполняется break; { //LeaveCriticalSection(&CritSec); break; } //LeaveCriticalSection(&CritSec); код ужасен т к написан новичком - суть в баге. приятно отдохнуть.
UTeX В C++Bulder'е 6 у меня строчка с break не скомпилилась компилятором вообще И при любом условии туда не заходила. Бывает у него иногда какие-то приколы нехорошие. Я добавил фиктивную команду, типа: Код (Text): if ( y > 100) { iii = iii; break; } - и компилятор скомпилил инструкцию и после этого при у > 100 он заходит в тело условия С чем это связано к сожалению сказать не могу.
UTeX Смею предположить, что раз помогла критическая секция, то проблема в многопоточности. Маловероятно что у борланда такой баг в компиляторе. А вот если один поток вошёл в функцию, а другой из неё ещё не выходил, то может быть что угодно. К сожалению архив посмотреть не могу, так как на теперешней работе стоит прокся с фильтром на архивы.
А в чём ошибка? Если отлаживать по шагам, или поставить точку остановки, то отладчик действительно пройдётся по или остановится на break; внутри if ( y > 100)...., даже если на самом деле условие не выполняется. НО, цикл НЕ прерывается - переходим на следующую после блока if команду. Т.е. реально break; не выполняется! И при отладке в окне CPU всё в порядке. Просто такая особенная реакция отладчика на блок if, в котором ничего кроме break нет. Стоит добавить любую команду, например y=y; перед или даже после break; (!!!) и отладчик будет благополучно проскакивать мимо содержимого блока if когда условие не выполняется. Это, конечно, для особо впечатлительных, так как логика программы не меняется. CRITICAL_SECTION ни причём, просто вариант типа y=y.
Здесь все, ИМХО, связано с тем, как (криво) Builder сопоставляет адреса машинных команд реальным строкам кода. То есть реально break не исполняется, даже когда на него показывает отладчик. То есть: Код (Text): if ( y > 100 ) { break; // пустой блок - адрес его начала совпадает с адресом следующего оператора после него. } AnyOperator; Если же внутрь блока поставить любой оператор, делающий хоть что-то, то все встанет на свои места.
Похоже на глюк оптимизатора. Я с похожим встречался в BC++ 3.1 - однажды не прикомпиливались куски printf, scanf для работы с плавающей запятой, и что-то похожее на описаное бывало. Приходилось шаманствовать с настройками компилятора, исходники и спец. батники для этого правда потеряны :-( Как вариант - попробуй переменные определить как глобальные, или локальные, но не в середине кода. Вариант2 - явное задание типа ( y < (float)100 ), но вряд ли. На дату не посмотрел
UTeX Это случаем не баг, связанный с установкой BreakPoint? У меня тоже на Билдере 6.* "проскакивает" одну инструкцию (приходится ставить BP на следующую). А еще это м.б. действительно связано с оптимизацией (вроде ставишь BP на один break или continue, а на деле нужно ее ставить совсем в другом месте.
Показал бы автор лучше машинный код, и я больше склоняюсь к тому что это вовсе не глюк оптимизатора. Наверно ИДЕ билдера глючит.
Еще интереснее: //баг есть: int y = 0; for( y = 0; y < 100; ++y) if( y == 10 ) break; //бага НЕТ: int y = 0; for( ; y < 100; ++y) if( y == 10 ) break;