Выражения фильтров и их значения
Параметр выражение_фильтра в операторе except вычисляется сразу же после того, как возникает исключение. В качестве выражения может выступать литеральная константа, вызов функции фильтра (filter function) или условное выражение. В любом случае выражение должно возвращать одно из следующих трех значений:
1. EXCEPTION_EXECUTE_HANDLER — система выполняет операторы блока обработки исключений, как показано на рис. 4.1 (см. программу 4.1). Это соответствует обычному случаю.
2. EXCEPTION_CONTINUE_SEARCH — система игнорирует данный обработчик исключений и пытается найти обработчик исключений в охватывающем блоке, продолжая этот процесс аналогичным образом до тех пор, пока не будет найден обработчик исключений.
3. EXCEPTION_CONTINUE_EXECUTION — система немедленно возвращает управление в точку, в которой возникло исключение. В случае некоторых исключений дальнейшее выполнение программы невозможно, но если такие попытки делаются, то генерируется повторное исключение.
Рис. 4.1. SEH, блоки и функции
Ниже приведен простой пример, в котором обработчик исключений используется для удаления временного файла в тех случаях, когда исключение возникает в теле цикла. Заметьте, что ключевое слово __try может быть применено к любому блоку, включая блоки, связанные с операторами while, if или любым другим оператором ветвления. В данном примере возникновение любого исключения приводит к удалению временного файла и закрытию дескриптора, после чего выполнение цикла возобновляется.
GetTempFileName(TempFile, …);
while (…) __try {
hFile = CreateFile(TempFile, …, OPEN_ALWAYS, …);
SetFilePointer(hFile, 0, NULL, FILE_END);
WriteFile(hFile, …);
i = *p; /* В этом месте программы возможно возникновение исключения адресации. */
CloseHandle (hFile);
…
} __except (EXCEPTION_EXECUTE_HANDLER) {
CloseHandle(hFile);
DeleteFile(TempFile);
/* Переход к выполнению очередной итерации цикла. */
}
/* Сюда передается управление после нормального завершения цикла.
Каждый раз при возникновении исключения дескриптор временного файла закрывается, а сам файл удаляется. */
Ниже описана логика приведенного выше фрагмента кода.
• На каждой итерации цикла в конце файла добавляются новые данные.
• В случае возникновения исключения во время выполнения итерации цикла все данные, накопленные во временном файле, будут уничтожены, и если еще остались невыполненные итерации, то во временном файле начнут накапливаться новые данные.
• В случае возникновения исключения на последней итерации файл прекращает существование. В любом случае файл будет содержать все данные, сгенерированные после предыдущего исключения.
• В примере отмечена лишь одна точка программы, в которой возможно возникновение исключения, хотя исключения могут возникнуть в любой точке тела цикла.
• Чтобы гарантировать закрытие дескриптора файла, это делается как при выходе из цикла, так и перед началом очередной итерации цикла.