Ответ «потому что обычно не возвращает только 0 или 1». Я нашел эту ветку от сообщества разработчиков программного обеспечения, которая хотя бы частично отвечает на ваш вопрос. Вот два основных момента, первый из принятых ответов:
Целое число дает больше места, чем байт, для сообщения об ошибке. Он может быть перечислен (возврат 1 означает XYZ, возврат 2 означает ABC, возврат 3, означает DEF и т. Д.) Или использоваться в качестве флагов (0x0001
означает, что произошел сбой, 0x0002
означает, что произошел сбой, 0x0003
значит и то и то не получилось). Ограничение всего лишь одним байтом может легко исчерпать флаги (только 8), поэтому решение, вероятно, заключалось в использовании целого числа.
Интересный момент также поднимает Кейт Томпсон :
Например, на диалекте C, используемом в Plan 9 операционная система main
обычно объявляется как функция void
, но статус выходавозвращается в вызывающую среду, передавая строковый указатель в функцию exits()
. Пустая строка обозначает успех, а любая непустая строка обозначает какой-то сбой. Это может быть реализовано, если main
вернуть char*
результат.
Вот еще один интересный момент из форума unix.com :
(Некоторые из перечисленных ниже могут быть специфичными для x86.)
Возвращаясь к первоначальному вопросу: где хранится статус выхода? Внутри ядра.
Когда вы вызываете exit (n), младшие 8 битов целого числа n записываются в регистр процессора. Реализация системного вызова ядра затем скопирует его в связанную с процессом структуру данных.
Что если ваш код не вызывает exit ()? Библиотека времени выполнения c, ответственная за вызов main (), будет вызывать exit () (или какой-либо его вариант) от вашего имени. Возвращаемое значение main (), которое передается в среду выполнения c в регистре, используется в качестве аргумента для вызова exit ().
Относится к последней цитате, вот еще один из cppreference.com
5) Выполнение возврата (или неявного возврата по достижении конца main) эквивалентно первому выходу из функции в обычном режиме (что уничтожает объекты с помощью автоматическогодлительность хранения), а затем вызывать std :: exit с тем же аргументом, что и аргумент возврата. (затем std :: exit уничтожает статические объекты и завершает программу)
Наконец, я нашел этот действительно крутой пример здесь (хотя автор поста ошибочно говорит, чтовозвращенный результат является возвращаемым значением по модулю 512). После компиляции и выполнения следующего:
int main() {
return 42001;
}
на POSIX-совместимой моей * системе echo $?
возвращает 17. Это потому, что 42001 % 256 == 17
, который показывает, что 8 бит данныхна самом деле используется. Имея это в виду, выбор int
гарантирует, что достаточно места для передачи информации о состоянии завершения программы, потому что согласно этому ответу , соответствие стандарту C ++ гарантирует, что размер int
(вбиты)
не может быть меньше 8. Это потому, что он должен быть достаточно большим, чтобы содержать «восьмибитные кодовые единицы формы кодировки Unicode UTF-8».
РЕДАКТИРОВАТЬ:
* Как Эндрю Хенле указал в комментарии:
Полностью POSIX-совместимая система делает все int
возвращаемое значениедоступно, а не только 8 бит. См. pubs.opengroup.org / onlinepubs / 9699919799 / basedefs / signal.h.html : «Если si_code
равно CLD_EXITED
, то si_status
содержит выходное значение процесса; в противном случае, он равен сигналу, который заставил процесс изменить состояние. Выходное значение в si_status
должно быть равным полному выходному значению (то есть значение, переданное _exit()
, _Exit()
или exit()
или возвращено из main()
); оно не должно быть ограничено младшими восемью битами значения. "
Думаю, это еще более веский аргумент в пользу использования int
для типов данных меньшего размера.