EXCEPTION_CONTINUE_SEARCH
Приведенные до сих пор примеры были ну просто детскими Чтобы немного встрях нуться, добавим вызов функции:
char g_szBuffer[100];
void FunclinRoosevelt2()
{
char *pchBuffer = NULL;
__try
{
FuncAtude2(pchBuffer);
}
__except (OilFilter2(&pchBuffer))
{
MessageBox(...);
}
}
void FuncAtude2(char *sz)
{
*sz = 0;
}
LONG OilFilter2(char **ppchBuffer)
{
if (*ppchBuffer == NULL)
{
*ppchBuffer = g_szBuffer;
return(EXCEPTION_CONTINUE_EXECUTION);
}
return(EXCEPTION_EXECUTE HANDLER);
}
При выполнении FunclinRoosevelt2 вызывается FuncAtude2, которой передается NULL. Последняя приводит к исключению. Как и раньше, система проверяет выраже ние в фильтре исключений, связанном с последним исполняемым блоком try. В на шем примере это блок try в FunclinRoosevelt2, поэтому для оценки выражения в филь тре исключений система вызываег OilFilter2 (хотя исключение возникло в FuncAtude2).
Замесим ситуацию еще круче, добавив другой блок try-except
char g_szBuffer[100];
void FunclinHoosevelt3()
{
char *pchBuffer = NULL;
__try
{
FuncAtude3(pchBuffer);
}
__except (OilFilter3(&pch8uffer))
{
Message8ox(...);
}
}
void FuncAtude3(char *sz)
{
__try
{
*sz = 0;
}
__except (EXCEPTION_CONTINUE_SEARCH)
{
// этот код никогда не выполняется
...
}
}
LONG OilFilter3(Utar **ppchBuffer)
{
if (*ppchBuffer == NULL)
{
*ppchBuffer = g_szBuffer;
return(EXCEPTION CONTINUE_EXECUTION);
}
return(EXCEPTIQN_EXECUTE_HANDLER);
}
Теперь, когда FuncAtude3 пытается занести 0 по адресу NULL, по-прежнему возбуж дается исключение, но в работу вступает фильтр исключений из FuncAtude3. Значе ние этого очень простого фильтра — EXCEPTIUN_CONTINUE_SEARCH. Данный иден тификатор указывает системе перейти к предыдущему блоку tty, которому соответ ствует блок except, и обработать его фильтр.
Так как фильтр в FuncAtude3 дает EXCEPTION_CONTINUE_SEARCH, система пере ходит к предыдущему блоку try (в функции FunclinRoOsevelt3) и вычисляет eго фильтр OilFilter3. Обнаружив, что значение pchBuffer равно NULL, OilFilter3 меняет его так, чтобы оно указывало на глобальный буфер, и сообщает системе возобновить выпол нение с инструкции, вызвавшей исключение Это позволяет выполнить код в блоке try функции FuncAtude3, но, увы, локальная переменная sz в этой функции не измене на, и возникает новое исключение Опять бесконечный цикл!
Заметьте, я сказал, что система переходит к последнему исполнявшемуся блоку try, которому соответствует блок except, и проверяет его фильтр Это значит, что система пропускает при просмотре цепочки блоков любые блоки try, которым соответствуют блоки finally (а не except). Причина этого очевидна, в блоках finally нет фильтров ис ключений, а потому и проверять в них нечего. Если бы в последнем примере Func Atude3 содержала вместо except, система начала бы проверять фильтры исключений с OilFilter3 в FunclinRroosevelt3
Дополнительную информацию об EXCEPTION_CONTINUE_SEARCH см. в главе 25.