Проектирование графического интерфейса пользователя______________313

операторов раздела _finally программа не знает, произошло ли исключение, и
если произошло, то какое именно. Проверки наличия исключения с помощью фун-
кций ExceptAddr и ExceptObject, специально предназначенных для этого, внутри
раздела _finally ни к чему не приводят, так как исключение генерируется после
выполнения этих операторов.

4.9.2.3 Защита кода зачистки при завершении приложения —
функции atexit и exit

В предыдущем разделе рассматривалась защита кода зачистки в блоке. Одна-
ко не все можно сделать на уровне блока. Поэтому полезно предусмотреть зачистку
при завершении приложения.

Один из способов завершения приложения — вызов функции exit:

Unclude <stdlib.h>
void exitfint status);

Параметр status определяет код завершения. Обычно 0 соответствует норма-
льному завершению, а значение, отличное от нуля — аварийному при наличии
ошибки выполнения. Можно, но не обязательно, использовать для задания значе-
ния status предопределенные константы: EXIT_FAILURE — аварийное заверше-
ние, EXIT_SUCCESS — нормальное.

Например:

exit(O);            // нормальное завершение
exit(EXIT_SUCCESS); // нормальное завершение
exit(l);            // аварийное завершение
exit(EXIT_SUCCESS); // аварийное завершение

При завершении приложения с помощью exit перед прекращением работы за-
крываются все открытые файлы и очищаются все буфера вывода (печатается, нахо-
дящийся в них текст). Эти операции совершаются по умолчанию. Если же вам
надо произвести еще какие-то действия (например, уничтожить временные файлы
на диске), то вы можете зарегистрировать одну или несколько собственных функ-
ций, которые всегда автоматически будут выполняться перед действиями по умол-
чанию.

Регистрируются собственные функции завершения с помощью функции ate-
xit:

ftinclude <stdlib.h>
int atexit(void (JJSERENTRY * func)(void));

Здесь func — имя регистрируемой функции. Можно выполнить несколько вы-
зовов atexit, зарегистрировав таким образом несколько функций завершения. При
завершении приложения выполняться эти функции будут в обратной последовате-
льности: сначала — последняя из зарегистрированных, а в конце — зарегистриро-
ванная первой.

Например, следующий код определяет две функции завершения — myexiti и
myexit2:

void myexiti(void)
f

операторы зачистки
)

void myexit2(void)
(

операторы зачистки
I

Эти функции могут не объявляться в заголовочном файле, а просто включать-
ся в текст модуля.