Итак, как работает exit ()?

#c #exit

#c #выход

Вопрос:

Если я использую exit() , GCC не выдает предупреждения:

 int main()
{
    exit(EXIT_SUCCESS);
}
  

Если мы используем любую другую функцию, мы обязательно встретим такое предупреждение:

 warning: control reaches end of non-void function
  

Как exit() заставить родительскую функцию получать возвращаемое значение без использования return() , которое создает компилятор?

Ответ №1:

В GNU libc exit объявляется с помощью __attribute__((__noreturn__)) , которая сообщает gcc, что функция не возвращает.

Комментарии:

1. @Chris Jester-Young, не могли бы вы подробнее рассказать о __attribute__((__noreturn__)) ?

2. @compile-fan: google — твой друг: unixwiz.net/techtips/gnu-c-attributes.html

3. @compile-fan: Нет, это сообщает компилятору, что функция не вернется, таким образом, элемент управления никогда не дойдет до конца main, поэтому предупреждения нет.

4. @compile-fan: Попробуйте это: int main() {exit(0); printf("Peek-a-boo!n");} . «Peek-a-boo!» не печатается.

5. @compile-fan: Потому что exit указано для передачи своего аргумента родительскому процессу. На самом деле, код инициализации библиотеки C на самом деле просто вызывает ваш main этот способ: exit(main(argc, argv, envp)) , поэтому, будут ли ваши main возвраты или нет, не влияет на то, будет ли exit вызван.

Ответ №2:

Из документов:

Аргумент status возвращается в среду хоста.

И

Выдача инструкции return из функции main эквивалентна вызову функции exit с возвращаемым значением в качестве аргумента.

Это реализовано (в данном случае) через атрибут объявления функции ( __noreturn__ ), который сообщает компилятору, что это можно рассматривать как возврат (или, более правильно, что функция не вернет, поэтому управление никогда не достигнет конца main).

Ответ №3:

вместо

  exit(EXIT_SUCCESS);
  

есть

  return(EXIT_SUCCESS);
  

Комментарии:

1. @Dietrich — Вы заметили, что вопрос был изменен до вашего комментария, но после моего ответа?

2. Здесь требуются круглые скобки (exit — это функция): exit(EXIT_SUCCESS); Круглые скобки здесь ничего не делают (return — это оператор): return(EXIT_SUCCESS); Использование круглых скобок с return похоже на их использование здесь: (1);

3. @davep — конечно, это просто стиль. Я мог бы привести какой-нибудь безумный аргумент о макросах бла-бла-бла — но я не собираюсь заморачиваться — мне всегда нравятся операторы return с () , независимо от того, имеют они значение / выражение или нет.

4. Это может сбить новичков с толку.

5. Понятия не имею, что ты имеешь в виду @nikeee

Ответ №4:

Проблема в том, что вам не удалось включить stdlib.h , и что вы не компилируете с -std=c99 . В C99 main неявно возвращает 0, если вы выполняете его в конце.