Выполняет ли 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 для значений выхода более нюанс, чем нечетное / четное. На самом деле он использует что-то вроде младших трех битов для кодирования уровня серьезности. В целом, однако, уровни нечетной серьезности указывают на успех или различную информацию, а четные указывают на ошибки.