Haruskah saya mengembalikan EXIT_SUCCESS atau 0 dari main ()?

124

Ini pertanyaan sederhana, tetapi saya terus melihat jawaban yang bertentangan: haruskah rutinitas utama program C ++ kembali 0atau EXIT_SUCCESS?

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

atau

int main(){return 0;}

Apakah mereka sama persis? Haruskah EXIT_SUCCESShanya digunakan dengan exit()?

Saya pikir EXIT_SUCCESSakan menjadi pilihan yang lebih baik karena perangkat lunak lain mungkin ingin menganggap nol sebagai kegagalan, tetapi saya juga mendengar bahwa jika Anda kembali 0, kompiler dapat mengubahnya ke nilai yang berbeda.

Trevor Hickey
sumber
Apakah ini menjawab pertanyaan Anda? stackoverflow.com/questions/1188335/…
Blastfurnace
2
Jawaban tentang C90 ini memparafrasekan standar - 0dan EXIT_SUCCESSkeduanya ditafsirkan sebagai kesuksesan.
ta.speot. Adalah
Saya akan menanggapi di sini karena saya merasa orang lain akan membaca ini di masa mendatang. Pada dasarnya ada banyak paradigma tentang seperti apa "C yang benar" itu. Beberapa paradigma lebih suka menggunakan literal daripada makro, misalnya, daripada meneruskan NULL sebagai argumen, mereka mungkin meneruskan (const char *) 0 untuk menunjukkan bahwa itu bukan hanya nol, tetapi jika bukan nol, itu harus menjadi a penunjuk karakter konstan. Paradigma lain lebih suka menjadi tipe agnostik dan dengan menggunakan tipe makro, mereka dapat menghindari kebutuhan untuk mengubah basis kode mereka ketika hal-hal berubah secara radikal. Misalnya, banyak -
Dmitry
@Dmitry <continued> Definisi jenis Windows API tidak benar di platform yang lebih baru, tetapi karena itu makro, mereka memiliki cara mudah untuk mengubah semua jenis menjadi yang berfungsi dengan mendefinisikan ulang makro, dan sebagian besar jenis ini hanya diskalakan menurut definisi (mis. int berbeda pada platform yang berbeda). Untuk meringkas, gunakan hal-hal seperti EXIT_SUCCESS jika kode pengembalian penting dan mungkin berubah di masa mendatang, jika tidak mengembalikan 0 mungkin tampak seperti angka ajaib tetapi itu masih konvensi standar yang valid. kode kesalahan sebagian besar untuk program untuk menyalurkan hasil nomor dari satu ke yang lain, -
Dmitry
@Dmitry <continued> menggunakan kode kesalahan untuk men-debug program Anda agak lemah karena jika ia mengembalikan 0, itu adalah informasi yang sangat tidak berguna kecuali dalam beberapa kasus ketika ada kesalahan yang tidak tertangani dalam program yang dapat membuat program berhenti secara diam-diam, dan Anda perlu untuk memeriksa apakah kembali normal (0) atau terjadi kesalahan diam-diam. Angka yang dikembalikan lebih berguna untuk menyalurkan 0..255 dari satu program ke program lain berdasarkan inputnya, jika tidak, tidak ada alasan untuk memikirkannya: mengembalikan 0 atau menggunakan main yang telah dikompilasi sebelumnya yang menyejajarkan panggilan "init" kosong untuk tidak secara visual mengganggu Anda dengan pengembalian yang tidak berguna.
Dmitry

Jawaban:

151

EXIT_FAILURE, baik dalam pernyataan return mainatau sebagai argumen exit(), adalah satu-satunya cara portabel untuk menunjukkan kegagalan dalam program C atau C ++. exit(1)sebenarnya dapat menandakan penghentian yang berhasil di VMS, misalnya.

Jika Anda akan menggunakan EXIT_FAILUREsaat program Anda gagal, Anda sebaiknya menggunakannya EXIT_SUCCESSsaat berhasil, hanya demi kesimetrisan.

Di sisi lain, jika program tidak pernah memberi sinyal kegagalan, Anda dapat menggunakan salah satu 0atau EXIT_SUCCESS. Keduanya dijamin oleh standar untuk menandakan penyelesaian berhasil. (Hampir tidak mungkin yang EXIT_SUCCESSdapat memiliki nilai selain 0, tetapi nilainya sama dengan 0 pada setiap implementasi yang pernah saya dengar.)

Menggunakan 0memiliki keuntungan kecil yang tidak Anda perlukan #include <stdlib.h>di C, atau #include <cstdlib>di C ++ (jika Anda menggunakan returnpernyataan daripada menelepon exit()) - tetapi untuk program dengan ukuran signifikan apa pun Anda akan menyertakan stdlib secara langsung atau tidak langsung bagaimanapun.

Dalam hal ini, di C yang dimulai dengan standar 1999, dan di semua versi C ++, mencapai akhir main()tetap melakukan implisit return 0;, jadi Anda mungkin tidak perlu menggunakan salah satunya 0atau EXIT_SUCCESSsecara eksplisit. (Tapi setidaknya di C, saya menganggap gaya eksplisit return 0;sebagai gaya yang lebih baik.)

(Seseorang bertanya tentang OpenVMS. Saya sudah lama tidak menggunakannya, tetapi seingat saya, nilai status ganjil umumnya menunjukkan keberhasilan sedangkan nilai genap menunjukkan kegagalan. Implementasi C memetakan 0ke 1, sehingga return 0;menunjukkan penghentian yang berhasil. Nilai-nilai lain diteruskan tanpa perubahan , begitu return 1;juga menunjukkan penghentian yang berhasil. EXIT_FAILUREakan memiliki nilai genap bukan nol.)

Keith Thompson
sumber
@KeithThompson dapatkah Anda mengklarifikasi jawaban Anda sehubungan dengan VMS (OpenVMS?). Tidak jelas hubungan EXIT_SUCCESS / EXIT_FAILURE dengan 0 dan 1. Saya akan menjelaskan nilai ganjil / genap sebagai gantinya.
malat
@ malat: Apakah Anda benar-benar menggunakan VMS?
Keith Thompson
tidak, tidak pernah menggunakannya. Saya mencari jawaban kanonik, karena wikipedia menggunakan kata-kata yang berbeda .
malat
1
@Rhymoid: Ini ditentukan oleh C, bukan POSIX.
Keith Thompson
1
@DeanP: 0dan EXIT_SUCCESStidak dijamin memiliki nilai yang sama (saya sebutkan dalam jawaban saya), tetapi keduanya menunjukkan penghentian yang berhasil. EXIT_SUCCESSsecara gaya lebih baik jika Anda juga menggunakan EXIT_FAILURE, tetapi exit(0)tidak masalah.
Keith Thompson
25

Tidak masalah. Keduanya sama.

Kutipan Standar C ++:

Jika nilai status nol atau EXIT_SUCCESS, bentuk implementasi status penghentian berhasil dikembalikan.

Alok Save
sumber
12
Tidak masalah bagi kompiler, tapi mungkin masalah gaya.
celtschk
2
@celtschk: Materi gaya adalah berbasis persepsi alias Non Standardized sehingga tidak dihitung sebagai perbedaan. Anda hanya dapat membandingkan Apel dengan Apel bukan Apel dengan Pir.
Alok Hemat
3
Tidak ada jaminan itu EXIT_SUCCESS == 0. Di sisi lain, tidak ada alasan bagus untuk tidak melakukannya.
Keith Thompson
@KeithThompson: mengapa Tidak ada jaminan bahwa EXIT_SUCCESS == 0.? Tolong jelaskan lebih jelas.
Destructor
2
@PravasiMeet: Suatu sistem mungkin memiliki lebih dari satu nilai yang menunjukkan keberhasilan.
Keith Thompson
11

0, menurut definisi, adalah angka ajaib. EXIT_SUCCESS hampir secara universal sama dengan 0, cukup bahagia. Jadi mengapa tidak kembali / keluar 0?

keluar (EXIT_SUCCESS); sangat jelas artinya.

keluar (0); di sisi lain, berlawanan dengan intuisi dalam beberapa hal. Seseorang yang tidak terbiasa dengan perilaku shell mungkin berasumsi bahwa 0 == false == buruk, sama seperti penggunaan 0 lainnya di C. Tetapi tidak - dalam kasus khusus ini, 0 == sukses == baik. Untuk developer yang paling berpengalaman, tidak akan menjadi masalah. Tapi mengapa tersandung orang baru tanpa alasan sama sekali?

tl; dr - jika ada konstanta yang ditentukan untuk bilangan ajaib Anda, hampir tidak pernah ada alasan untuk tidak menggunakan konstanta di tempat pertama. Ini lebih mudah dicari, sering kali lebih jelas, dll. Dan tidak dikenakan biaya apa pun.

James
sumber
Saya pikir komentar Anda tentang orang yang mengharapkan 0 secara otomatis buruk adalah melenceng. Sangat banyak API menggunakan 0 untuk sukses, dan non-0 untuk kegagalan, bahkan di stdlib. Misalnya stdlib ( fclose(), setvbuf(), ...), POSIX ( listen(), pthread_create(), pipe(), ...), dan banyak, banyak perpustakaan lainnya (misalnya OpenGL [ glGetError()], zlib [ deflate()/ inflate()/ ...], SDL [ SDL_CreateWindowAndRenderer()/ ...], dan lebih).
Tim Čas
2
Tentu, ada contoh lain di mana 0 digunakan untuk 'sukses', tetapi dia benar tentang itu membingungkan.
Paul Wintz
10

Ini adalah cerita yang tidak pernah berakhir yang mencerminkan batasan (mitos) dari "interoperabilitas dan portabilitas di atas segalanya".

Apa yang program harus kembalikan untuk menunjukkan "sukses" harus ditentukan oleh siapa yang menerima nilai (sistem operasi, atau proses yang memanggil program) bukan oleh spesifikasi bahasa.

Tetapi programmer suka menulis kode dengan "cara portabel" dan karenanya mereka menciptakan model mereka sendiri untuk konsep "sistem operasi" yang mendefinisikan nilai-nilai simbolik untuk dikembalikan.

Sekarang, dalam skenario banyak-ke-banyak (di mana banyak bahasa berfungsi untuk menulis program ke banyak sistem), korespondensi antara konvensi bahasa untuk "berhasil" dan sistem operasi (yang tidak dapat diberikan oleh siapa pun untuk selalu sama) harus ditangani oleh implementasi khusus perpustakaan untuk platform target tertentu.

Tapi - sayangnya - konsep ini tidak begitu jelas pada saat bahasa C digunakan (terutama untuk menulis kernel UNIX), dan Gigagram buku yang ditulis dengan mengatakan "return 0 berarti sukses", karena itu benar pada OS di saat itu memiliki kompiler C.

Sejak saat itu, tidak pernah dibuat standarisasi yang jelas tentang bagaimana korespondensi tersebut harus ditangani. C dan C ++ memiliki definisi mereka sendiri tentang "nilai yang dikembalikan" tetapi tidak ada yang memberikan terjemahan OS yang tepat (atau lebih baik: tidak ada dokumentasi kompilator yang mengatakan apa pun tentangnya). 0 berarti sukses jika benar untuk UNIX - LINUX dan -untuk alasan independen- untuk Windows juga, dan ini mencakup 90% dari "komputer konsumen" yang ada, yang - dalam sebagian besar kasus - mengabaikan nilai yang dikembalikan (sehingga kami dapat diskusikan selama beberapa dekade, tapi tidak ada yang akan memperhatikan!)

Di dalam skenario ini, sebelum mengambil keputusan, tanyakan pertanyaan berikut: - Apakah saya tertarik untuk mengkomunikasikan sesuatu kepada penelepon tentang keberadaan saya? (Jika saya selalu mengembalikan 0 ... tidak ada petunjuk di balik semuanya) - Apakah penelepon saya memiliki kesepakatan tentang komunikasi ini? (Perhatikan bahwa satu nilai bukanlah konvensi: yang tidak mengizinkan representasi informasi apa pun)

Jika kedua jawaban ini tidak, mungkin solusi yang baik adalah tidak menulis pernyataan pengembalian utama sama sekali. (Dan biarkan kompilator untuk memutuskan, sehubungan dengan target bekerja).

Jika tidak ada konvensi di tempat, 0 = sukses memenuhi sebagian besar situasi (dan menggunakan simbol mungkin bermasalah, jika mereka memperkenalkan konvensi).

Jika ada konvensi, pastikan untuk menggunakan konstanta simbolik yang koheren dengannya (dan pastikan koherensi konvensi, bukan koherensi nilai, antar platform).

Emilio Garavaglia
sumber
4

Begitu Anda mulai menulis kode yang dapat mengembalikan banyak sekali status keluar, Anda mulai #definesemuanya. Dalam hal ini EXIT_SUCCESSmasuk akal dalam konteks bukan menjadi " angka ajaib ". Ini membuat kode Anda lebih mudah dibaca karena setiap kode keluar lainnya akan menjadi EXIT_SOMETHING. Jika Anda hanya menulis program yang akan dikembalikan setelah selesai, return 0valid, dan mungkin lebih bersih karena menunjukkan bahwa tidak ada struktur kode pengembalian yang canggih.

Phonon
sumber
0

Apa yang Anda kembalikan dari program hanyalah konvensi.

Tidak, saya tidak bisa memikirkan situasi apa pun di mana "EXIT_SUCCESS" bukan "0".

Secara pribadi, saya akan merekomendasikan "0".

MENURUT OPINI SAYA...

paulsm4
sumber
1
Saya telah memprogram C ++ selama 10 tahun dan masih tidak ingat apakah 0 berarti berhasil atau gagal dalam hal nilai kembali.
lahjaton_j
@lahjaton_j Saya mengerti. Ia mengira itu karena kontra intuitif: 0salah, dan banyak fungsi kembali 0gagal / tidak melakukan apa-apa.
arti-penting
-5

Beberapa kompiler mungkin membuat masalah dengan ini - pada kompiler Mac C ++, EXIT_SUCCESS bekerja dengan baik untuk saya, tetapi pada kompiler Linux C ++ saya harus menambahkan cstdlib untuk mengetahui apa itu EXIT_SUCCESS. Selain itu, mereka adalah satu dan sama.

Sangat pandai
sumber
Maksud saya di Mac EXIT_SUCCESS bekerja tanpa menyertakan cstdlib.
Ambidextrous
4
Jika EXIT_SUCCESSbekerja tanpa menyertakan salah satu <stdlib.h>atau <cstdlib>, beberapa header lain harus telah menentukannya, secara langsung atau tidak langsung. Di C ++, header #includestandar sama dengan header standar lainnya. Jika ini terkompilasi tanpa kesalahan: int main() { return EXIT_SUCCESS; }maka kompiler Anda mungkin bermasalah.
Keith Thompson