VisualC++ (как и многие другие среды разработки) содержит макросы, предназначенные специально для отладки. Например, макросы TRACE(), ASSERT() и VERIFY()
приносят огромную пользу в процессе разработки. Они предназначены для разных целей, но у всех трех макросов есть нечто общее — они не отягощают итоговый выполняемый файл. При построении отладочных версий вашей программы макросы ведут себя так, как им положено. Однако в «окончательной» версии они удаляются из программы (вместе с теми возможностями, которые ими обеспечивались).
Макрос TRACE()
посылает диагностические сообщения в окно отладчика. Правильно составленные сообщения образуют протокол событий, который можно просмотреть после выполнения программы (а средства удаленной отладки, о которой мы вскоре поговорим, позволяют сделать это даже во время работы программы). Макросы TRACE(), содержащие коды возврата и описания ошибок, помогают отыскать источники багов в ваших программах. Макрос TRACE()
в отличие от двух других нормально работает в полноэкранных приложениях DirectDraw, так что вы можете свободно пользоваться им (этот макрос регулярно встречается в программах на CD-ROM).
Макросы ASSERT() и VERIFY()
очень похожи друг на друга, что часто приводит к недоразумениям. На самом деле между ними существует очень важное различие. В отладочных версиях макросы ASSERT() и VERIFY() работают одинаково. Оба макроса вычисляют выражение, переданное им в качестве аргумента, и прекращают работу программы с выводом сообщения в том случае, если это выражение оказывается равным нулю. Отличие заключается в том, что в окончательной версии макрос ASSERT() вместе с вычисляемым выражением полностью удаляется из кода. С другой стороны, выражение макроса VERIFY() остается в программе. Макрос ASSERT() предназначен для проверки состояния переменных, а VERIFY() — для проверки функций. Выражение макроса ASSERT()
относится только к состоянию переменных и не является обязательной частью программы, поэтому его можно удалить из окончательной версии.
Использование макросов ASSERT() и VERIFY()
в полноэкранных приложениях DirectDraw осложняется тем, что при неудачной проверке выводится диалоговое окно. Несовместимость палитры может привести к искажению окна, а из-за переключения страниц окно может и вовсе не появиться на экране.
При таких затруднениях у вас есть два варианта: отказаться от ASSERT() и VERIFY()
или предоставить нестандартные версии, работающие в DirectDraw. Второй вариант предпочтительнее, и, как выясняется, он реализуется достаточно просто.
Если покопаться в заголовочных файлах MFC, вы увидите, что в отладочном режиме макрос ASSERT() определяется так:
|
#define ASSERT(f) do { if (!(f) && AfxAssertFailedLine(THIS_FILE, __LINE__)) AfxDebugBreak(); } while (0 |
|
#define ASSERT(f) do { if (!(f)) { if (GetDDWin()) { GetDDWin()->GetDDraw()->RestoreDisplayMode(); GetDDWin()->GetDDraw()->Release(); } AfxAssertFailedLine(THIS_FILE, __LINE__); AfxDebugBreak(); } } while (0) |
|
#define VERIFY(f) ASSERT(f) |
|
#define ASSERT(f) ((void)0) #define VERIFY(f) ((void)(f)) |
|
#ifdef _DEBUG #undef ASSERT #define ASSERT(f) do { if (!(f)) { if (GetDDWin()) { GetDDWin()->GetDDraw()->RestoreDisplayMode(); GetDDWin()->GetDDraw()->Release(); } AfxAssertFailedLine(THIS_FILE, __LINE__); AfxDebugBreak(); } } while (0) #endif _DEBUG |