Debug и Release компиляция
От: kaas Россия  
Дата: 19.05.04 10:32
Оценка:
Здравствуйте все!
Я уже довольно много раз сталкивался с тем, что поведение программы, скомпилированной в Дебуг может отличаться от поведения той же программы, скомпилированной в Релиз. В основном это, конечно, касалось ее надежности, то есть в Дебуге падает меньше. Но все же, хотелось бы еще узнать, чем работа с дебуговой версией в VS отличается от работы с Релиз версией.
Например, недавно писал прогу и не подумал сразу включить в нее файл stdio.h, выполняя при этом успешные вызовы printf и т.д. А когда переключился в Релиз и попробовал скомпилить, то компилятор сообщил, что не находит этого идентифера (printf), Почему же в Дебуге у него все есть? Может быть там еще какие-то фичи бывают интересные или полезные?
Может быть кто ссылкой поделится, чтобы про это почитать, или книгу порекомендует.
Re: Debug и Release компиляция
От: retalik www.airbandits.com/
Дата: 19.05.04 10:38
Оценка:
Здравствуйте, kaas, Вы писали:

K>Может быть кто ссылкой поделится, чтобы про это почитать, или книгу порекомендует.

http://www.rsdn.ru/article/vcpp/survrls.xml
Автор(ы): Dr. Joseph M. Newcomer
Дата: 18.06.2001
Статья посвящена проблемам перехода с Debug-версии на Release-версию. Рассматриваются
типичные ошибки, которые могут не проявляться в отладочной версии, но проявляются в финальной.
Обсуждается вопрос "ошибок компилятора" и вопросы необходимости оптимизации и ее побочные эффекты.
В последней редакции добавлен раздел посвященный проблеме совместимости динамических библиотек.


PS: найдено нажатием кнопки "найти ответ" в форме сообщения.
56 ссылок
Успехов,
Виталий.
Re: Debug и Release компиляция
От: Аноним  
Дата: 19.05.04 11:06
Оценка:
Здравствуйте, kaas, Вы писали:

Основное отличие в том, что в Debug програма работает медленнее, а в таком коде
Func1(...);
SendMessage(...); /*PostMessage*/
Func2(...);

В Debug к моменту вызова Func2 сообщение может быть уже обработано (хоть это и сучайность), а в Release нет.
Возможно пример не самый удачный, но основная проблемма это именно синхронизация кода, вдруг ставшего более быстрым.
Re: Debug и Release компиляция
От: Тим Россия  
Дата: 19.05.04 11:35
Оценка:
Здравствуйте, kaas, Вы писали:

K>Здравствуйте все!

K>Я уже довольно много раз сталкивался с тем, что поведение программы, скомпилированной в Дебуг может отличаться от поведения той же программы, скомпилированной в Релиз. В основном это, конечно, касалось ее надежности, то есть в Дебуге падает меньше. Но все же, хотелось бы еще узнать, чем работа с дебуговой версией в VS отличается от работы с Релиз версией.
K>Например, недавно писал прогу и не подумал сразу включить в нее файл stdio.h, выполняя при этом успешные вызовы printf и т.д. А когда переключился в Релиз и попробовал скомпилить, то компилятор сообщил, что не находит этого идентифера (printf), Почему же в Дебуге у него все есть? Может быть там еще какие-то фичи бывают интересные или полезные?
K>Может быть кто ссылкой поделится, чтобы про это почитать, или книгу порекомендует.

У меня была проблема в "глобальной неуникальности" имен структур + инициализация таких структур + оптимизация по скорости Майкрософтом (Борланд за таким замечен не был). Т.е. у меня есть структуры с одинаковыми именами, определенные в различных файлах. При определенных обстоятельствах и включенной оптимизации наблюдается Exeption. Причем таких "неуникальных" структур у меня с десяток, а падаю всего в двух случаях. Так и не смог докопаться, что заставляет компидятор тереть "нужные" участки памяти — пришлось структурки переименовывать...
Re[2]: Debug и Release компиляция
От: Denwer Россия  
Дата: 19.05.04 11:51
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, kaas, Вы писали:


А>Основное отличие в том, что в Debug програма работает медленнее, а в таком коде

А>
А>Func1(...);
А>SendMessage(...); /*PostMessage*/
А>Func2(...);
А>

А>В Debug к моменту вызова Func2 сообщение может быть уже обработано (хоть это и сучайность), а в Release нет.
А>Возможно пример не самый удачный, но основная проблемма это именно синхронизация кода, вдруг ставшего более быстрым.

Что то ты загнул немного, неужто ты думаешь что ВинАПИ создаст тебе дополнительный поток на обработку?
Какая тут синхронизация кода?
Re[2]: Debug и Release компиляция
От: Denwer Россия  
Дата: 19.05.04 11:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, kaas, Вы писали:


А>Основное отличие в том, что в Debug програма работает медленнее, а в таком коде

А>
А>Func1(...);
А>SendMessage(...); /*PostMessage*/
А>Func2(...);
А>

А>В Debug к моменту вызова Func2 сообщение может быть уже обработано (хоть это и сучайность), а в Release нет.
А>Возможно пример не самый удачный, но основная проблемма это именно синхронизация кода, вдруг ставшего более быстрым.

Добавление: проблема именно синхронизация кода, вдруг ставшего более быстрым, получается тогда, когда ты синронизируешь с помощью
всяких задержек (Sleep например). Такой подход вообще не применим, и при нормальной синхронизации(спец объектами) никакое
увеличение производительности не повлияет на корректную работу.
Re[2]: Debug и Release компиляция
От: SWW Россия  
Дата: 19.05.04 12:11
Оценка:
А>Основное отличие в том, что в Debug програма работает медленнее, а в таком коде

Это далеко не основное отличие, а пример с PostMessage — вообще ерунда. Обычно различие возникает из-за неинициализированных переменных. Бывает также, если ты пишешь за пределы массива, но в дебуге эта часть памяти оказывается не используемой, поэтому ничего не портится. А в релизе там оказываются какие-то переменные, они портятся и... тогда я тебе не завидую. Кстати, обычно в таком случае программист объявляет глючным оптимизатор.
Re[2]: Debug и Release компиляция
От: Tan4ik Россия  
Дата: 19.05.04 13:23
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Основное отличие в том, что в Debug програма работает медленнее, а в таком коде

А>
А>Func1(...);
А>SendMessage(...); /*PostMessage*/
А>Func2(...);
А>

А>В Debug к моменту вызова Func2 сообщение может быть уже обработано (хоть это и сучайность), а в Release нет.
А>Возможно пример не самый удачный, но основная проблемма это именно синхронизация кода, вдруг ставшего более быстрым.

При SendMessage можно быть уверенным, что к моменту вызова Func2 сообщение уже обработано как в Debug, так и в Release.
---
С уважением,
Лазарев Андрей
Re[2]: Debug и Release компиляция
От: Павел Кузнецов  
Дата: 19.05.04 23:53
Оценка:
> У меня была проблема в "глобальной неуникальности" имен структур + инициализация таких структур + оптимизация по скорости Майкрософтом (Борланд за таким замечен не был). Т.е. у меня есть структуры с одинаковыми именами, определенные в различных файлах. При определенных обстоятельствах и включенной оптимизации наблюдается Exeption. Причем таких "неуникальных" структур у меня с десяток, а падаю всего в двух случаях. Так и не смог докопаться, что заставляет компидятор тереть "нужные" участки памяти — пришлось структурки переименовывать...

Ничто не заставляет. С другой стороны, ничто не заставляет его проделывать специальную работу, чтобы избегать подобных ситуаций. Передача на вход транслятору программы, в которой в разных файлах есть одноименные классы с разным содержимым, стандарт квалифицирует как неопределенное поведение, соответственно, снимая с компилятора/компоновщика всякую ответственность за сколько-нибудь разумный код на выходе.
Posted via RSDN NNTP Server 1.9 alpha
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Debug и Release компиляция
От: kaas Россия  
Дата: 20.05.04 05:57
Оценка:
Здравствуйте, retalik, Вы писали:

R>Здравствуйте, kaas, Вы писали:


K>>Может быть кто ссылкой поделится, чтобы про это почитать, или книгу порекомендует.

R>http://www.rsdn.ru/article/vcpp/survrls.xml
Автор(ы): Dr. Joseph M. Newcomer
Дата: 18.06.2001
Статья посвящена проблемам перехода с Debug-версии на Release-версию. Рассматриваются
типичные ошибки, которые могут не проявляться в отладочной версии, но проявляются в финальной.
Обсуждается вопрос "ошибок компилятора" и вопросы необходимости оптимизации и ее побочные эффекты.
В последней редакции добавлен раздел посвященный проблеме совместимости динамических библиотек.


R>PS: найдено нажатием кнопки "найти ответ" в форме сообщения.

R>56 ссылок

Выход за массив и дрю ошибки с памятью, отладочные макросы и т.д. — это мы уже проходили а вот почему в Дебуговой версии включены файлы типа "stdio.h" или там какое-то namespace используется или еще что-то — вот это не понятно. Может кроме этого еще какие-нибудь наворочки Дебуговых версий бывают?
Re[2]: Debug и Release компиляция
От: kaas Россия  
Дата: 20.05.04 06:00
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, kaas, Вы писали:


А>Основное отличие в том, что в Debug програма работает медленнее, а в таком коде

А>
А>Func1(...);
А>SendMessage(...); /*PostMessage*/
А>Func2(...);
А>

А>В Debug к моменту вызова Func2 сообщение может быть уже обработано (хоть это и сучайность), а в Release нет.
А>Возможно пример не самый удачный, но основная проблемма это именно синхронизация кода, вдруг ставшего более быстрым.

Да, у меня тоже была пара примеров, когда код, типа такого:
А>
А>Func1(...);
А>MessageBox(...);
А>Func2(...);
А>

работал нормально, а без MessageBox на второй функции вылетал (ну — упрощенно, но идея такая). Как будто там что-то прорабатывает во время сообщения и дальше становится хорошо жить
Re[3]: Debug и Release компиляция
От: Denwer Россия  
Дата: 20.05.04 06:39
Оценка:
Здравствуйте, kaas, Вы писали:

K>Здравствуйте, Аноним, Вы писали:


А>>Здравствуйте, kaas, Вы писали:


А>>Основное отличие в том, что в Debug програма работает медленнее, а в таком коде

А>>
А>>Func1(...);
А>>SendMessage(...); /*PostMessage*/
А>>Func2(...);
А>>

А>>В Debug к моменту вызова Func2 сообщение может быть уже обработано (хоть это и сучайность), а в Release нет.
А>>Возможно пример не самый удачный, но основная проблемма это именно синхронизация кода, вдруг ставшего более быстрым.

K>Да, у меня тоже была пара примеров, когда код, типа такого:

А>>
А>>Func1(...);
А>>MessageBox(...);
А>>Func2(...);
А>>

K>работал нормально, а без MessageBox на второй функции вылетал (ну — упрощенно, но идея такая). Как будто там что-то прорабатывает во время сообщения и дальше становится хорошо жить

Данная проблема из-за ошибок именно программиста, а именно порча стека. Вот например в MFC широко используется карта сообщений, где все построено на макросах, так вот в 6-й студии там стояло сишное преобразование т.е. (Type), и если программист неправельно объявит функцию компилятор не отругается, но вот чудеса появяться во время работы. Вывод: будьте бдительны!!!

ЗЫ: Кстати в 7-й студии изменили на static_cast, тепереча лажа всякая не компилируется.
Re: Debug и Release компиляция
От: Кодт Россия  
Дата: 23.05.04 21:46
Оценка: 12 (1)
Здравствуйте, kaas, Вы писали:

<>

А ещё в копилку граблей могу подкинуть — unspecified behaviour (неописуемое поведение).

Например, порядок вычисления подвыражений:
int x = foo() + bar() + xyz();

где функции имеют побочные эффекты.
От перемены мест слагаемых... а тем более, от порядка вычисления... сумма-то не меняется, а вот всё остальное может поплыть.
Как правило, в дебаге аргументы вычисляются справа налево (в порядке записи на стек для конвенции _cdecl); а в релизе могут быть перетасованы самым затейливым образом.

Кстати, подобным способом можно нарваться и на неопределённое поведение: если побочные эффекты — это модификация и чтение переменной, оказавшиеся между точек следования.
int i = 1;
i = i++ + ++i; // любимая фишка

Как эта штука будет оптимизирована — одному богу ведомо. И не споткнётся ли в этом месте программа...

Другой случай неописуемого поведения — нарушение volatile.
Дебаг-версия считает все переменные волатильными° (не в смысле приписывания им формального квалификатора volatile, а в практическом использовании). Релиз-версия может (и должна) при оптимизации учитывать неволатильность.
° volatile — неустойчивый, изменчивый. Имхо, русские переводы не передают точный смысл этого термина, поэтому написал транслитерацию.
int value = 1;

int one_million()
{
    int sum = 0;
    for(int i=0; i<1000000; ++i) sum += value;
    return sum;
}
// в релизе будет просто: return value * 1000000;

void some_thread_or_interrupt()
{
    ...
    value = 1-value;
    ...
}

А если чтение/запись такой переменной не атомарно (т.е. поток может быть вытеснен в процессе обращения, на середине) — то и до неопределённого поведения недалеко.
... << RSDN@Home 1.1.2 stable >>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.