Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
Стандарт С определяет две константы, которые следует использовать для полной переносимости на не-POSIX системы:
EXIT_SUCCESSПрограмма завершилась без проблем. Для обозначения успеха может также использоваться ноль.
EXITВ программе была какая-нибудь проблема.
На практике использование лишь этих значений довольно ограничивает. Вместо этого следует выбрать небольшой набор кодов возврата, документировать их значения и использовать. (Например, 1 для ошибок опций командной строки и аргументов, 2 для ошибок ввода/вывода, 3 для ошибок данных и т.д.) Для удобочитаемости стоит использовать константы
#defineenumКогда достаточно двоичного разделения успех/неудача, педантичный программист использует
EXIT_SUCCESSEXIT_FAILUREreturnexit()ЗАМЕЧАНИЕ. Для родительского процесса доступны лишь восемь наименее значимых битов значения. Поэтому следует использовать значения в диапазоне 0–255. Как мы вскоре увидим, у чисел 126 и 127 есть традиционные значения (помимо простого «неуспешно»), которых ваши программы должны придерживаться.
Поскольку имеют значение лишь восемь наименее значимых битов, вы никогда не должны использовать отрицательные статусы завершения. Когда из небольших отрицательных чисел выделяются восемь последних битов, они превращаются в большие положительные значения! (Например. -1 становится 255, а -5 становится 251.) Мы видели книги по программированию на С, в которых это понималось неправильно — не дайте сбить себя с толку
9.1.5.2. Возвращение из
main()Программа может естественно завершиться одним из двух способов: посредством использования одной из описанных далее функций или возвратившись из
main()abort()/* Правильно */ /* Неправильно */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 <stdlib.h> /* ISO С */void exit(int status);void _Exit(int status);int atexit(void (*function)(void));Эти функции работают следующим образом:
void exit(int status)Эта функция завершает программу,
statusexit()atexit()stdio.h> FILEtmpfile()open()creat()exit()void _Exit(int status)Эта функция в сущности идентична функции POSIX
_exit()int atexit(void (*function)(void))functionexit()nftw()nftw()atexit()atexit()errnoСледующая программа не делает полезной работы, но демонстрирует, как работает
atexit()/* ch09-atexit.c --- демонстрация atexit(). Проверка ошибок для краткости опущена. */