Проект нормально работает в дебаг конфигурации, но не работает в релиз.
Отключив оптимизацию в релиз версии все заработало. Может кто подскажет, как найти
то заветное место в програме , и как с этим бороться ?
Здравствуйте Crucifier, Вы писали:
C>Проект нормально работает в дебаг конфигурации, но не работает в релиз. C>Отключив оптимизацию в релиз версии все заработало. Может кто подскажет, как найти C>то заветное место в програме , и как с этим бороться ?
Здравствуйте Crucifier, Вы писали:
C>Проект нормально работает в дебаг конфигурации, но не работает в релиз. C>Отключив оптимизацию в релиз версии все заработало. Может кто подскажет, как найти C>то заветное место в програме , и как с этим бороться ?
Первым делом установи четвертый уровень предупреждений для проекта, и внимательно изучи все предупреждения компилятора. Постарайся избавиться от них путем реорганизации кода, а не отключением #pragma warning( disable:C???? ).
Просмотри все макросы для debug версии, которые используются в проекте, на предмет того, что при сборке release не выкидывается рабочий код.
Например: int object.calculateValue() //при проверке должен возвращать число не равное нулю.
ASSERT( 0 != object.calculateValue() ) //такой вызов будет отсутствовать в релизе
Следующая конструкция содержит проверку в debug версии, и в release выполняет правильный вызов
int iRet = object.calculateValue();
ASSERT( iRet );
Но, в первую очередь надо все таки избавиться от предупреждений, чтобы убрать все неоднозначности кода.
Здравствуйте Crucifier, Вы писали:
C>Проект нормально работает в дебаг конфигурации, но не работает в релиз. Отключив оптимизацию в релиз версии все заработало. C>Может кто подскажет, как найти то заветное место в програме, и как с этим бороться ?
Раз знаешь, что не работает, значит, знаешь, что не работает, значит, знаешь место, где не работает. Либо показывай код, либо сам разбирайся, почему оптимизация так портит код.
У меня была такая проблема при вычислении орта вектора. Возвращался совсем не орт (модуль вектора != 1) и совсем другого направления. Исправилось переделкой функции (что уж там влияло на оптимизацию, как-то не было времени анализировать).
Здравствуйте Vi2, Вы писали:
Vi2>Раз знаешь, что не работает, значит, знаешь, что не работает, значит, знаешь место, где не работает. Либо показывай код, либо сам разбирайся, почему оптимизация так портит код.
Vi2>У меня была такая проблема при вычислении орта вектора. Возвращался совсем не орт (модуль вектора != 1) и совсем другого направления. Исправилось переделкой функции (что уж там влияло на оптимизацию, как-то не было времени анализировать).
Типичные грабли — это надежда на
— выравнивание элементов структуры (вместо использования pragma pack)
— заведомый порядок вычисления в выражениях (то, что называется unspecified & undefined behaviour) — это вызов функций с побочным эффектом, множественные присваивания и автоинкременты
— использование арифметики (в т.ч. битовой) вместо булевских операций
Например,
printf("hello ") + printf("world")
может напечатать и hello world, и worldhello .
struct X
{
DWORD a;
DWORD b;
DWORD c;
};
const size_t sizeofx = 12; // а вдруг в релизе выравнивание на 16 байт?
Здравствуйте Кодт, Вы писали:
К>Типичные грабли — это надежда на К>- выравнивание элементов структуры (вместо использования pragma pack) К>- заведомый порядок вычисления в выражениях (то, что называется unspecified & undefined behaviour) — это вызов функций с побочным эффектом, множественные присваивания и автоинкременты К>- использование арифметики (в т.ч. битовой) вместо булевских операций
Вполне возможно. Но пути компилятора неисповедимы.
Если ты имеешь в виду именно мою ситуацию, то вот полный исходный код (исключая h-файлы)
Может быть компилятор смутили "__" перед именами аргументов (ну вот такая подпрограммка досталась по наследству, я убрал потом эти символы), может, похожесть подпрограмм, может ещё что. Я не знаю. Не исследовал. Но режим оптимизации давал неверный результат.
P>на сколько я помню для double точное сравнение не проходит, P>и что-то подобное уже обсуждалось недавно.
Еще как проходит, просто в большинстве случаев это совсем не то, чего желает программист. А вот в данном коде со сравнением все нормально — если dist != 0.0, на него можно делить
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: Проблема из-за оптимизации в Release ver
От:
Аноним
Дата:
10.09.02 10:57
Оценка:
Здравствуйте Sergey, Вы писали:
S>Если dist != 0.0, на него можно делить
Здравствуйте Vi2, Вы писали:
Vi2>Можно ли делить или нельзя, нравится фрагмент или нет — вопрос не об этом.
Vi2>А в том, что данный фрагмент не содержит никаких подводных камней. А вот оптимизация их подкинула. После этого я к оптимизации отношусь настороженно.
Да верю я, верю. У нас в конторе вообще оптимизацию запрещено включать без особой на то необходимости
Vi2>Но может, я их не вижу, эти камни?! Вот об этом лучше сказать.
Ты б сначала сказал, в чем ошибка заключалась, привел фрагменты ассемблера с оптимизацией и без, вот тогда может чего и сказали бы. А навскидку — результаты с оптимизацией и без нее должны отличаться при малых dist, рулит этим опция /Op.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте Sergey, Вы писали:
S>В данном примере — можно. Если там NaN или денормализованное значение, исключение при вычислении X_len2 должно выскочить.
Если signaling NaN — да, а если quiet NaN — нет.
... << J 1.0 alpha 4 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте Павел Кузнецов, Вы писали:
S>>В данном примере — можно. Если там NaN или денормализованное значение, исключение при вычислении X_len2 должно выскочить.
ПК>Если signaling NaN — да, а если quiet NaN — нет.
А после деления на quiet NaN хуже не станет — вроде как quiet NaN в результате получиться должен.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте Sergey, Вы писали:
S>>>В данном примере — можно. Если там NaN или денормализованное значение, исключение при вычислении X_len2 должно выскочить.
ПК>>Если signaling NaN — да, а если quiet NaN — нет.
S>А после деления на quiet NaN хуже не станет — вроде как quiet NaN в результате получиться должен.
Однако исключение не выскочит. Кроме того, возвращаясь к контексту дискуссии, это вполне могло вызвать разницу в результатах в debug и release.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте Sergey, Вы писали:
S>Ты б сначала сказал, в чем ошибка заключалась, привел фрагменты ассемблера с оптимизацией и без, вот тогда может чего и сказали бы. А навскидку — результаты с оптимизацией и без нее должны отличаться при малых dist, рулит этим опция /Op.
Это было где-то в промежутке 1995-1997, точно не помню. Какая версия VC тоже. Помню только отношение к оптимизации после казуса.
Это как студенческий фольклор об уравнении Шредингера.
— "Помнишь уравнение Шредингера? Завтра спрашивать будут!"
— "Только вывод".
— "Да?! И какой вывод?"
— "Сложное уравнение". (с) КВН НГУ
А ошибку я уже описывал: возвращался совсем не орт (модуль вектора != 1) и совсем другого направления. Смотрел в режиме с отладкой этого модуля (чтобы точку останова было можно поставить). Что-то там творилось с регистрами плавающего процессора, наоптимизировал компилятор, млин. Видимо, константу пытался удержать, да не правильно что-то сделал — умножал на компонент вектора [0] все остальные [1],[2]. Насколько я понял при проходе по шагам в ассемблере. Но сейчас у меня нет "этих фрагментов ассемблера с оптимизацией и без", потому как тогда не знал RSDN (а то бы запостил их сюда раньше), а сейчас уже не смоделировать.
PS. Никакими Nan и прочим там даже не пахло.
Ладно, не придавайте этой теме значения. Просто я хотел показать, что не всё просто и в простом случае.
Здравствуйте Павел Кузнецов, Вы писали:
ПК>Здравствуйте Sergey, Вы писали:
S>>>>В данном примере — можно. Если там NaN или денормализованное значение, исключение при вычислении X_len2 должно выскочить.
ПК>>>Если signaling NaN — да, а если quiet NaN — нет.
S>>А после деления на quiet NaN хуже не станет — вроде как quiet NaN в результате получиться должен.
ПК>Однако исключение не выскочит.
IMHO, оно и не нужно. Я имел в виду, что проверка на ноль там стоит совершенно правильно, и любое исключение, которое может выскочить при делении, выскочит раньше. Я ж не могу в каждом предложении повторять всю предысторию обсуждения — работать же тоже надо
ПК>Кроме того, возвращаясь к контексту дискуссии, это вполне могло вызвать разницу в результатах в debug и release.
Вообще-то речь шла о разном поведении оптимизированного и неоптимизированного кода, а вовсе не debug vs release. Но все равно, не вижу, с чего бы тут дебаг от релиза отличался, если только человек сам флаги сопра не покрутил по разному — по дефолту вроде все одинаковое.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте Sergey, Вы писали:
ПК>>Однако исключение не выскочит.
S>IMHO, оно и не нужно. Я имел в виду <...> Я ж не могу в каждом предложении повторять всю предысторию обсуждения — работать же тоже надо
Ладно, проехали: это было излишнее буквоедство с моей стороны.
ПК>>Кроме того, возвращаясь к контексту дискуссии, это вполне могло вызвать разницу в результатах в debug и release.
S>Вообще-то речь шла о разном поведении оптимизированного и неоптимизированного кода, а вовсе не debug vs release.
А это уже излишняя небрежность с моей стороны Имелась в виду именно оптимизация.
S>Но все равно, не вижу, с чего бы тут дебаг от релиза отличался,
Если в оптимизированном варианте получалось, что dist == 0.0, а в неоптимизированном dist != 0, или наоборот, то результаты X_unit2/X_unit3 вполне могли различаться.
S>если только человек сам флаги сопра не покрутил по разному — по дефолту вроде все одинаковое.
Практически, думаю, что, скорее всего, в оптимизированном варианте, помимо прочего, как, по-моему, уже кто-то замечал, мог включаться флаг /Op.
... << J 1.0 alpha 4 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен