A3. […] При проблеме с release-версией рекомендую следующее:
1. Откомпилировать программу с оптимизацией, но и с подключенной отладочной информацией. Для этого она должна генерироваться компилятором и подключаться линковщиком. Дальше запускаем под отладчиком и смотрим ошибки.
2. После локализации ошибки проанализировать соответствие ассемблерного кода (Ctrl+F7 в MSVC) исходному коду.
Типичные причины подобных ошибок:
1. Оптимизатор дооптимизировался до маразма
2. В отладочном режиме свободные области памяти заполняются определенным значением. В релизе этого не происходит. Выплывают огрехи с отсутствием инициализации переменных
3. Время выполнения участков кода становится другим. Могут всплыть ошибки, связанные с некачественной синхронизацией различных ниток и т.п.[…]
A4. Могу сказать только одно – ЕЩЕ РАЗ проверьте свой код. У меня такие ситуации были на заре моей практики. Это было ужасно… Часы проведенные в Debuge – куча MessageBox в Release – и ничего – ошибка не исчезала. А было на самом деле вот что. Под Debug компайлер напихивает кучу разных вещей которых нет в Release версии – как например обнуление указателей, проверку на выделение памяти и т.д. Я приведу здесь один глюк который реально у меня встретился и привел к вышеупомянутым последствиям. Был какой-то класс и какая структура данных
struct MyStruct { … };
class MyClass {
MyStruct* pStruct;
…
}
И мне надо было в конструкторе класса выделить память под pStruct – но я этого НЕ СДЕЛАЛ. И было вот что под Debug обращение типа pStruct[0] не вызывало никаких осложнений – а под Release вылетало тут же. Поэтому следите за УКАЗАТЕЛЯМИ. Это самая кульная вещь в С/C++ но и самая геморройная (может быть грубовато – но это так)
A5. По поводу скрытых ошибок в программах, не ленитесь в критических местах использовать TRACE0, а перед использованием указателей проверяйте содержимое
HRESULT AnyMethod(MyClass* pPointer) {
if(pPointer != NULL) {
// и только здесь начинайте с ним работать!
} else {
TRACE0("Получен пустой указатель");
return S_FALSE;
}
}
Q. У меня есть вопрос по обработке события WM_KEYUP. Играя с диалогом, обнаружил, что он сам никак не реагирует на нажатия клавы. Как решение, использовал следующий способ: для каждого типа контрола делал свой класс, который реагирует на WM_KEYUP, и в обработчике этого события пересылал сообщение окну диалога. […] Но такой способ отдаeт некоторой горбатостью, может быть существует какое-то более элегантное решение?