Чи слід повернути EXIT_SUCCESS або 0 від main ()?


124

Це просте запитання, але я все ще бачу суперечливі відповіді: чи повинен повертатися основний розпорядок програми C ++ 0чи EXIT_SUCCESS?

#include <cstdlib>
int main(){return EXIT_SUCCESS;}

або

int main(){return 0;}

Вони точно те саме? Чи EXIT_SUCCESSслід використовувати тільки при exit()?

Я подумав, що EXIT_SUCCESSце буде кращим варіантом, оскільки інше програмне забезпечення може вважати нуль невдачею, але я також чув, що якщо ви повернетесь 0, компілятор може все-таки змінити його на інше значення.


Чи відповідає це на ваше запитання? stackoverflow.com/questions/1188335 / ...
доменний

2
Ця відповідь про С90 перефразовує стандарт - 0і EXIT_SUCCESSобидва трактуються як успіх.
ta.speot.is

Я відповім тут, оскільки відчуваю, що хтось ще читатиме це у майбутньому. В основному існує багато парадигм про те, як виглядає "правильний C". Деякі парадигми вважають за краще використовувати літерали над макросами, наприклад, замість передачі NULL в якості аргументу вони можуть передавати (const char *) 0, щоб вказати, що це не просто нуль, але якщо він не був нулем, він повинен бути постійний вказівник символів. Інші парадигми вважають за краще вводити агностичні типи, і використовуючи макро типи, вони можуть уникнути необхідності змінювати свою кодову базу, коли все докорінно змінюється. Наприклад, багато хто -
Дмитро

@Dmitry <continued> Визначення типів Windows API не є правильним у нових платформах, але оскільки вони були макросами, у них був простий спосіб змінити всі типи на ті, що працюють, перевизначивши макрос, і багато з цих типів просто масштабували за визначенням (наприклад, int відрізняється на різних платформах). Підводячи підсумок, використовуйте такі речі, як EXIT_SUCCESS, якщо код повернення має значення і може змінитися в майбутньому, інакше повернення 0 може здатися магічним числом, але це все-таки абсолютно дійсна стандартна умова. код помилки здебільшого в програмах передає результати передачі номерів один на інший, -
Дмитро

@Dmitry <continued> використання кодів помилок для налагодження вашої програми начебто слабкий, оскільки якщо вона повертає 0, це досить непотрібна інформація, за винятком випадків, коли в програмі є невідомі незроблені помилки, які можуть змусити програму мовчки зламатися, і вам потрібно щоб перевірити, чи нормально він повертався (0) чи виникла тиха помилка. Повернення числа корисніше для передачі 0..255 від однієї програми до іншої на основі їх входів, інакше немає приводу думати про це: або поверніть 0, або використовуйте попередньо складений основний, який вводить недійсний виклик "init" не візуально дратувати вас марною віддачею.
Дмитро

Відповіді:


151

EXIT_FAILURE, або в операторі зворотного зв’язку, mainабо в якості аргументу exit(), - це єдиний портативний спосіб вказати на збій у програмі C або C ++. exit(1)може фактично сигналізувати про успішне припинення, наприклад, VMS.

Якщо ви збираєтеся використовувати, EXIT_FAILUREколи програма не працює, то ви також можете використовувати EXIT_SUCCESSїї, коли вона вдається, просто заради симетрії.

З іншого боку, якщо програма ніколи не сигналізує про збій, ви можете використовувати або 0або EXIT_SUCCESS. Обидва вони гарантуються стандартом для сигналізації про успішне завершення. (Навряд чи можливо, що воно EXIT_SUCCESSмогло б мати значення, відмінне від 0, але воно дорівнює 0 для кожної реалізації, про яку я коли-небудь чув).

Використання 0має незначну перевагу, яке вам не потрібно #include <stdlib.h>в C, або#include <cstdlib> C ++ (якщо ви використовуєте returnоператор, а не дзвінкиexit() ) - але для програми будь-якого значного розміру ви будете включати stdlib прямо або опосередковано все одно.

З цього питання, на C, починаючи зі стандарту 1999 року, і в усіх версіях C ++, досягнення кінця все одно main()неявне return 0;, тож вам може не потрібно використовувати 0абоEXIT_SUCCESS явно. (Але принаймні в С я вважаю явний return 0;кращим стилем.)

(Хтось запитав про OpenVMS. Я його не використовував давно, але, як я пам'ятаю, непарні значення статусу зазвичай позначають успіх, а навіть значення позначають збій. Реалізація C відображається 0на 1так, що return 0;вказує на успішне припинення. Інші значення передаються незмінними , тому return 1;також вказує на успішне припинення. EXIT_FAILUREматиме ненульове парне значення.)


@KeithThompson Ви могли б уточнити свою відповідь стосовно VMS (OpenVMS?). Незрозуміло співвідношення EXIT_SUCCESS / EXIT_FAILURE з 0 і 1. Я б пояснив це непарні / парні значення.
малат

@malat: Ви фактично використовуєте VMS?
Кіт Томпсон

ні, ніколи не використовував. Я шукав канонічну відповідь, оскільки у Вікіпедії було використано інше формулювання .
малат

1
@Rhymoid: Це вказано через C, а не POSIX.
Кіт Томпсон

1
@DeanP: 0і EXIT_SUCCESSне гарантується, що вони матимуть однакове значення (я це згадував у своїй відповіді), але вони обоє позначають успішне припинення. EXIT_SUCCESSстилістично краще, якщо ви також використовуєте EXIT_FAILURE, але exit(0)це нормально.
Кіт Томпсон,

25

Не важливо. Обидва однакові.

Стандартні котирування C ++:

Якщо значення статусу дорівнює нулю або EXIT_SUCCESS, повертається визначена реалізацією форма успішного припинення статусу.


12
Для компілятора це не має значення, але це може мати значення як стиль.
celtschk

2
@celtschk: Матеріальність стилю - це сприйняття, засноване також на Non Standardized, що не вважається різницею. Можна порівняти лише яблука з яблуками, а не яблука з грушами.
Alok Зберегти

3
Гарантії цього немає EXIT_SUCCESS == 0. З іншого боку, немає вагомих причин цього не бути.
Кіт Томпсон

@KeithThompson: чому немає гарантії, що EXIT_SUCCESS == 0.? Будь ласка, поясніть це більш чітко.
Деструктор

2
@PravasiMeet: Система може мати більше одного значення, яке вказує на успіх.
Кіт Томпсон

11

0, за визначенням, магічне число. EXIT_SUCCESS майже повсюдно дорівнює 0, досить щасливо. То чому б не просто повернути / вийти 0?

вихід (EXIT_SUCCESS); є рясно зрозумілим за значенням.

вихід (0); з іншого боку, є певним чином контрінтуїтивним. Хтось, не знайомий з поведінкою оболонки, може припустити, що 0 == false == погано, як і будь-яке інше використання 0 в C. Але ні - в цьому окремому випадку 0 == успіх == хороший. Для більшості досвідчених розробників це не буде проблемою. Але чому поїхати до нового хлопця абсолютно без причин?

tl; dr - якщо для вашого магічного числа є визначена константа, майже ніколи немає причини не використовувати константу в першу чергу. Це більше пошуку, часто зрозуміліше тощо, і це нічого не коштує.


Я думаю, що ваші коментарі про людей, які очікують, що "0" автоматично буде поганим, не вдається. Дуже багато API використовують 0 для успіху, а non-0 для відмови навіть у stdlib. Наприклад , STDLIB ( fclose(), setvbuf(), ...), POSIX ( listen(), pthread_create(), pipe(), ...), і багато, багато інших бібліотеки (наприклад , OpenGL [ glGetError()], Zlib [ deflate()/ inflate()/ ...], SDL [ SDL_CreateWindowAndRenderer()/ ...], і більше).
Тім Час

2
Звичайно, є й інші випадки, коли 0 використовується для "успіху", але він прав, що він бентежить.
Пол Вінц

10

Це нескінченна історія, яка відображає межі (міф) "сумісності та портативності для всіх".

Те, що програма повинна повернути для позначення "успіху", має визначатися тим, хто отримує значення (Операційна система або процес, який викликав програму), не мовою.

Але програмісти люблять писати код "переносним способом", і тому вони вигадують власну модель для концепції "операційної системи", визначаючи символьні значення для повернення.

Тепер у сценарії "багато-до-багатьох" (де багато мов служать для запису програм у багато систем) відповідність між мовною конвенцією для "успіху" та однією операційною системою (яку ніхто не може дати завжди бути однаковою) повинна повинні оброблятися конкретною реалізацією бібліотеки для певної цільової платформи.

Але - на жаль - це поняття, де на час розгортання мови C не було зрозуміло (головним чином для написання ядра UNIX), і гігаграми книг, де написано висловом "return 0 означає успіх", оскільки це було правдою в ОС на того часу мав компілятор С.

Відтоді не було зроблено чіткої стандартизації щодо того, як слід вести таку кореспонденцію. C і C ++ мають власне визначення поняття "повернення значень", але ніхто не надає належного перекладу ОС (а ще краще: жодна документація компілятора нічого про це не говорить). 0 означає успіх, якщо це справедливо і для UNIX - LINUX та - для незалежних причин - і для Windows, і це охоплює 90% існуючих "споживчих комп'ютерів", що - у більшості випадків - не враховує повернутого значення (тому ми можемо обговорюйте десятиліттями, бо ніхто ніколи не помітить!)

У цьому сценарії, перш ніж приймати рішення, задайте наступні питання: - Чи зацікавлений я щось повідомити своєму абонентові про існуючий? (Якщо я завжди завжди повертаю 0 ... немає жодної підказки за всім) - Чи мій абонент має умови про це спілкування? (Зауважте, що одне значення не є умовою: це не дозволяє подати інформацію)

Якщо обох відповіді немає, напевно, хорошим рішенням є взагалі не писати основну заяву про повернення. (І дозвольте компілятору прийняти рішення стосовно цілі, над якою працює).

Якщо не існує умовних умов 0 = успіх відповідає більшості ситуацій (а використання символів може бути проблематичним, якщо вони вводять умову).

Якщо конвенції існують, переконайтеся, що використовуються символічні константи, когерентні їм (і забезпечте узгодженість конвенції, а не цілісну когерентність між платформами).


4

Як тільки ви почнете писати код, який може повернути безліч статусів виходу, ви починаєте #defineїх усі. У цьому випадку EXIT_SUCCESSмає сенс в контексті не бути " магічним числом ". Це робить ваш код більш читабельним, оскільки буде кожен інший вихідний код EXIT_SOMETHING. Якщо ви просто написати програму, яка повернеться після її завершення,return 0 є дійсною і, ймовірно, ще чистішою, тому що це говорить про відсутність складної структури повернення коду.


0

Те, що ви повертаєтесь із програми, - це лише умова.

Ні, я не можу придумати жодних обставин, коли "EXIT_SUCCESS" не став би би "0".

Особисто я рекомендував би "0".

ІМХО ...


1
Я програмую C ++ протягом 10 років і досі не можу згадати, чи означає 0 успіх чи провал у плані повернених значень.
lahjaton_j

@lahjaton_j Я розумію. Здається, це тому, що це протилежно інтуїтивно: 0помилково, і багато функцій повертаються 0при відмові / нічого не роблять.
значення-питання

-4

Якщо ви використовуєте EXIT_SUCCESS, ваш код стане більш портативним.

http://www.dreamincode.net/forums/topic/57495-return-0-vs-return-exit-success/


5
Я дуже сумніваюся, що це робить ваш код більш або менш портативним.
Бенджамін Ліндлі

9
Ні, не буде. Стандарт гарантує, що 0 і EXIT_SUCCESSобидва означають успішне припинення.
Кіт Томпсон

-5

Деякі компілятори можуть створити проблеми з цим - на компіляторі Mac C ++ EXIT_SUCCESS працював добре для мене, але на компіляторі Linux C ++ мені довелося додати cstdlib, щоб знати, що таке EXIT_SUCCESS. Крім цього, вони є одними і тими ж.


Я мав на увазі на Mac EXIT_SUCCESS працював, не включаючи cstdlib.
Вельмизбірний

4
Якщо це EXIT_SUCCESSпрацює без включення будь-якого <stdlib.h>або <cstdlib>, якийсь інший заголовок повинен був це визначити прямо чи опосередковано У програмі C ++ звичайні заголовки звичайні для #includeінших стандартних заголовків. Якщо це компілюється без помилок: int main() { return EXIT_SUCCESS; }тоді ваш компілятор, ймовірно, баггі.
Кіт Томпсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.