Выполняет ли exit () что-то особенное, чего не делает return?
Некоторые компиляторы для необычных платформ exit()
могут преобразовать свой аргумент в значение выхода вашей программы, в то время как возвращение из main()
может просто передать значение непосредственно в среду хоста без какого-либо перевода.
Стандарт требует идентичного поведения в этих случаях (в частности, он говорит, что возвращение чего-либо, из- int
совместимого main()
должно быть эквивалентно вызову exit()
с этим значением). Проблема в том, что разные ОС имеют разные соглашения для интерпретации выходных значений. Во многих (МНОГО!) Системах 0 означает успех, а все остальное - неудача. Но, скажем, в VMS нечетные значения означают успех, а четные - неудачу. Если вы вернули 0 из main()
, пользователь VMS увидит неприятное сообщение о нарушении доступа. На самом деле не было нарушения прав доступа - это было просто стандартное сообщение, связанное с кодом ошибки 0.
Затем появился ANSI и благословил, EXIT_SUCCESS
и в EXIT_FAILURE
качестве аргументов вы могли бы передать exit()
. Стандарт также говорит, что exit(0)
должен вести себя идентично exit(EXIT_SUCCESS)
, так что большинство реализаций определяют EXIT_SUCCESS
его 0
.
Поэтому стандарт ставит вас в тупик в VMS, поскольку не оставляет стандартного способа вернуть код ошибки, который имеет значение 0.
Поэтому компилятор VAX / VMS C начала 1990-х годов не интерпретировал возвращаемое значение main()
, а просто возвращал любое значение в среду хоста. Но если бы вы использовали exit()
его, он сделал бы то, что требовал стандарт: преобразовал EXIT_SUCCESS
(или 0
) в код успеха и EXIT_FAILURE
в общий код ошибки. Чтобы использовать EXIT_SUCCESS
, вы должны были передать его exit()
, вы не могли вернуть его main()
. Я не знаю, сохранили ли такое поведение более современные версии этого компилятора.
Портативная программа на Си раньше выглядела так:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, World!\n");
exit(EXIT_SUCCESS); /* to get good return value to OS */
/*NOTREACHED*/ /* to silence lint warning */
return 0; /* to silence compiler warning */
}
В стороне: Если я правильно помню, соглашение VMS для значений выхода более нюанс, чем нечетное / четное. На самом деле он использует что-то вроде младших трех битов для кодирования уровня серьезности. В целом, однако, уровни нечетной серьезности указывают на успех или различную информацию, а четные указывают на ошибки.