int main(int argc, char **argv) int main(int argc, char **argv)
{ {
/* здесь код */ /* здесь код */
return 0; /* ?? Что возвращает main()? */
} }
Стандарт С 1999 г. указывает, что при выпадении в конце, поведение функции main()
void — плохая мысль, которая может вести лишь к ошибочному коду.)Возвращенное из main()
wait() и waitpid()».ЗАМЕЧАНИЕ
. На системах GNU/Linux управляемая компилятором команда c99 запускает компилятор с соответствующими опциями, так что возвращаемое значение при выпадении из конца функции равно 0. Простой gcc этого не делает.9.1.5.3. Функции завершения
Другим способом естественного завершения программы является вызов функций завершения. Стандарт С определяет следующие функции:
#include
void exit(int status);
void _Exit(int status);
int atexit(void (*function)(void));
Эти функции работают следующим образом:
void exit(int status)
Эта функция завершает программу, status
exit() вызывает все функции, зарегистрированные с помощью atexit(), сбрасывает на диск и закрывает все открытые потоки <stdio.h> FILE* и удаляет все временные файлы, созданные tmpfile() (см. раздел 12.3.2 «Создание и открытие временных файлов»). Когда процесс завершается, ядро закрывает любые оставшиеся открытыми файлы (которые были открыты посредством open(), creat() или через наследование дескрипторов), освобождает его адресное пространство и освобождает любые другие ресурсы, которые он мог использовать. exit() никогда не возвращается.void _Exit(int status)
Эта функция в сущности идентична функции POSIX _exit()
int atexit(void (*function)(void))
function
exit() запускает функцию обратного вызова перед закрытием файлов и завершением. Идея в том, что приложение может предоставить одну или более функций очистки, которые должны быть запущены перед окончательным завершением работы. Предоставление функции называется ее nftw() обсуждались в разделе 8.4.3.2 «Функция обратного вызова nftw()»; здесь та же идея, хотя atexit() вызывает каждую зарегистрированную функцию лишь однажды.)atexit()
errno.Следующая программа не делает полезной работы, но демонстрирует, как работает atexit()
/* ch09-atexit.c --- демонстрация atexit().
Проверка ошибок для краткости опущена. */
/*
* Функции обратного вызова здесь просто отвечают на вызов.
* В настоящем приложении они делали бы больше. */
void callback1(void) { printf("callback1 called\n"); }
void callback2(void) { printf("callback2 called\n"); }
void callback3(void) { printf("callback3 called\n"); }
/* main --- регистрация функций и завершение */
int main(int argc, char **argv) {
printf("registering callback1\n"); atexit(callback1);