Main () 'den EXIT_SUCCESS mi yoksa 0 mı döndürmeliyim?


124

Bu basit bir soru, ancak çelişkili cevaplar görmeye devam ediyorum: bir C ++ programının ana rutini geri mi dönmeli 0yoksa EXIT_SUCCESS?

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

veya

int main(){return 0;}

Tam olarak aynı şey mi? Meli EXIT_SUCCESSile kullanılmalıdır exit()?

Daha EXIT_SUCCESSiyi bir seçenek olacağını düşündüm çünkü diğer yazılımlar sıfırı başarısızlık olarak kabul etmek isteyebilir, ancak aynı zamanda geri dönerseniz 0, derleyicinin yine de farklı bir değere değiştirebileceğini duydum .



2
C90 hakkındaki bu cevap , standardı açıklıyor0 ve EXIT_SUCCESSher ikisi de başarı olarak yorumlanıyor.
ta.speot.

Gelecekte başka birinin bunu okuyacağını düşündüğüm için burada yanıt vereceğim. Temelde "doğru C" nin neye benzediğine dair birçok paradigma vardır. Bazı paradigmalar makrolar yerine değişmez değerleri kullanmayı tercih ederler; örneğin, bağımsız değişken olarak NULL geçirmek yerine, bunun yalnızca bir boş olmadığını belirtmek için (const char *) 0 değerini geçebilirler, ancak boş değilse, bir sabit karakter işaretçisi. Diğer paradigmalar, türden bağımsız olmayı tercih eder ve makro türlerini kullanarak, işler kökten değiştiğinde kod tabanlarını değiştirme ihtiyacından kaçınabilirler. Örneğin, birçok -
Dmitry

@Dmitry <continued> Windows API tür tanımları yeni platformlarda doğru değildir, ancak makro oldukları için, tüm türleri makroyu yeniden tanımlayarak çalışanlara dönüştürmenin kolay bir yolunu bulmuşlardır ve bu türlerin çoğu, tanıma göre ölçeklendirilmiştir. (örneğin, int farklı platformlarda farklıdır). Özetlemek gerekirse, dönüş kodu önemliyse ve gelecekte değişebilirse EXIT_SUCCESS gibi şeyler kullanın, aksi takdirde 0 döndürmek sihirli bir sayı gibi görünebilir, ancak bu hala mükemmel bir şekilde geçerli standart kuraldır. hata kodu çoğunlukla programların sonuçları birinden diğerine
Dmitry

@Dmitry <continued>, programınızda hata ayıklamak için hata kodları kullanmak biraz zayıftır çünkü 0 döndürürse, programın sessizce bozulmasına neden olabilecek bir programda ele alınmamış hataların olduğu bazı durumlar dışında oldukça işe yaramaz bir bilgidir. normal olarak dönüp dönmediğini (0) veya sessiz bir hata oluşup oluşmadığını kontrol etmek için. Numara dönüşü, girdilerine bağlı olarak bir programdan diğerine 0..255 aktarımı için daha kullanışlıdır, aksi takdirde bunu düşünmek için bir neden yoktur: ya 0 döndürür ya da görsel olarak değil bir void "init" çağrısını satır içine alan önceden derlenmiş bir main kullanın gereksiz dönüşle seni kızdırır.
Dmitry

Yanıtlar:


151

EXIT_FAILURE, bir C veya C ++ programındaki başarısızlığı göstermenin tek taşınabilir yolu, içindeki bir dönüş ifadesinde mainveya bir argüman olarak exit(). exit(1)aslında VMS'de başarılı bir sonlandırma sinyali verebilir.

Eğer kullanıyor gidiyoruz EXIT_FAILUREprogram başarısız olduğunda, o zaman sen de kullanabilir EXIT_SUCCESSBaşarılı olduğunda sadece simetri uğruna.

Öte yandan, program hiçbir zaman hata sinyali vermiyorsa, ya 0da kullanabilirsiniz EXIT_SUCCESS. Her ikisi de standart tarafından başarıyla tamamlandığını belirtmek için garanti edilir. ( EXIT_SUCCESS0'dan başka bir değere sahip olması neredeyse imkansızdır, ancak şimdiye kadar duyduğum her uygulamada 0'a eşittir.)

Kullanmanın C veya C ++ ' da 0ihtiyaç duymadığınız küçük bir avantajı vardır ( aramak yerine bir ifade kullanıyorsanız ) - ancak herhangi bir önemli boyuttaki bir program için stdlib'i doğrudan veya dolaylı olarak dahil edeceksiniz. neyse.#include <stdlib.h>#include <cstdlib>returnexit()

Bu nedenle, 1999 standardından başlayarak C'de ve tüm C ++ sürümlerinde, sonuna ulaşmak zaten main()örtük bir return 0;durumdur, bu nedenle ikisinden birini 0veya EXIT_SUCCESSaçıkça kullanmanız gerekmeyebilir . (Ama en azından C'de, açık bir return 0;tarzın daha iyi olduğunu düşünüyorum.)

(Biri uzun zamandır bunu kullanmadım. OpenVMS sorulduğunda, ancak bu bile değerler yetmezliğini işaret ederken ben genelde anlamında olabildikleri başarı garip durum değerlerini hatırlayın. C uygulaması eşler 0için 1böylece return 0;başarılı sonlandırma gösterir. Diğer değerler değişmeden geçer , dolayısıyla return 1;başarılı sonlandırmayı da gösterir. EXIT_FAILUREsıfır olmayan bir çift değere sahip olacaktır.)


@KeithThompson, VMS (OpenVMS?) İle ilgili cevabınızı netleştirebilir misiniz? EXIT_SUCCESS / EXIT_FAILURE ile 0 ve 1 arasındaki ilişki net değil. Bunun yerine tek / çift değerlerini açıklardım.
malat

@malat: Gerçekten VMS kullanıyor musunuz?
Keith Thompson

hayır, hiç kullanmadım. Wikipedia farklı bir ifade kullandığı için kanonik bir cevap arıyordum .
malat

1
@Rhymoid: Bu, POSIX ile değil, C ile belirtilir.
Keith Thompson

1
@DeanP: 0ve EXIT_SUCCESSaynı değere sahip olma garantisi yok ( cevabımda bundan bahsetmiştim), ancak ikisi de başarılı bir sonlandırmayı ifade ediyor. EXIT_SUCCESSDaha iyi üslup ise eğer siz de kullandığınız EXIT_FAILUREama exit(0)ok.
Keith Thompson

25

Sorun değil. İkisi de aynı.

C ++ Standart Alıntılar:

Durumun değeri sıfır veya EXIT_SUCCESS ise, başarılı sonlandırma durumunun uygulama tanımlı bir formu döndürülür.


12
Derleyici için önemli değildir, ancak stil açısından önemli olabilir.
celtschk

2
@celtschk: Tarz meselesi algıya dayalıdır, yani Standardize Değildir, bu bir fark olarak sayılmaz. Sadece Elmaları ile Elmaları değil, Elmaları ve Armutları karşılaştırabilirsiniz.
Alok Save

3
Bunun garantisi yok EXIT_SUCCESS == 0. Öte yandan, olmaması için iyi bir neden yok.
Keith Thompson

@KeithThompson: Neden EXIT_SUCCESS == 0 garantisi yok? Lütfen daha net açıklayın.
Destructor

2
@PravasiMeet: Bir sistemin başarıyı gösteren birden fazla değeri olabilir.
Keith Thompson

11

0, tanımı gereği sihirli bir sayıdır. EXIT_SUCCESS neredeyse evrensel olarak 0'a eşittir, yeterince mutlu. Öyleyse neden 0'a dönüp / çıkmıyoruz?

çıkış (EXIT_SUCCESS); anlam olarak bolca açıktır.

çıkış (0); Öte yandan, bazı yönlerden mantıksızdır. Kabuk davranışına aşina olmayan biri, C'deki diğer her 0 kullanımında olduğu gibi 0 == false == kötü olduğunu varsayabilir. Ama hayır - bu özel durumda, 0 == başarı == iyi. Çoğu deneyimli geliştirici için sorun olmayacak. Ama neden yeni adamı kesinlikle sebepsiz yere gezdirelim?

tl; dr - sihirli sayınız için tanımlanmış bir sabit varsa, ilk etapta sabiti kullanmamanız için neredeyse hiçbir neden yoktur. Daha aranabilir, genellikle daha net vb. Ve size hiçbir maliyeti yoktur.


0'ın otomatik olarak kötü olmasını bekleyen insanlar hakkındaki yorumlarınızın uygun olmadığını düşünüyorum. Stdlib'de bile birçok API başarı için 0'ı ve başarısızlık için 0'ı kullanmaz. Örneğin stdlib ( fclose(), setvbuf(), ...), POSIX ( listen(), pthread_create(), pipe(), ...) ve birçok, birçok diğer kütüphaneler (örneğin OpenGL [ glGetError()], zlib [ deflate()/ inflate()/ ...], SDL [ SDL_CreateWindowAndRenderer()/ ...] ve Daha).
Tim Čas

2
Elbette, 0'ın 'başarı' için kullanıldığı başka durumlar da var, ancak kafa karıştırıcı olduğu konusunda haklı.
Paul Wintz

10

Bu, "birlikte çalışabilirlik ve her yerde taşınabilirlik" in sınırlarını (bir efsane) yansıtan bitmeyen bir hikaye.

Programın "başarı" yı belirtmek için ne döndürmesi gerektiği, bir dil belirtimine göre değil, değeri kimin aldığına (İşletim sistemi veya programı çalıştıran işlem) göre tanımlanmalıdır.

Ancak programcılar "taşınabilir yolla" kod yazmayı severler ve bu nedenle geri dönecek sembolik değerleri tanımlayan "işletim sistemi" kavramı için kendi modellerini icat ederler.

Şimdi, çoktan çoğa bir senaryoda (birçok dilin birçok sisteme program yazmaya hizmet ettiği), "başarı" için dil geleneği ile işletim sistemi arasındaki yazışma (hiç kimsenin her zaman aynı olmasını sağlayamayacağı) belirli bir hedef platform için bir kütüphanenin özel uygulamasıyla ele alınacaktır.

Ancak - ne yazık ki - C dilinin konuşlandırıldığı sırada o kadar net olmayan bu kavramlar (esas olarak UNIX çekirdeğini yazmak için) ve "dönüş 0 başarı anlamına gelir" diyerek yazılan kitapların Gigagramları, çünkü bu, işletim sistemi için geçerliydi. o zaman bir C derleyicisine sahip.

O andan itibaren, böyle bir yazışmanın nasıl ele alınması gerektiğine dair net bir standardizasyon yapılmadı. C ve C ++ 'nın kendi "dönüş değerleri" tanımı vardır, ancak hiç kimse uygun bir işletim sistemi çevirisi sağlamaz (veya daha iyisi: hiçbir derleyici dokümantasyonu bu konuda bir şey söylemez). 0 UNIX için doğruysa başarı anlamına gelir - LINUX ve -bağımsız nedenlerden dolayı- Windows için de ve bu, mevcut "tüketici bilgisayarlarının"% 90'ını kapsar, çoğu durumda - dönüş değerini göz ardı eder (böylece yapabiliriz onlarca yıldır tartışın, ama kimse fark etmeyecek!)

Bu senaryonun içinde, bir karar vermeden önce şu soruları sorun: - Arayan kişiye mevcut durumum hakkında bir şey iletmek ister miyim? (Eğer her zaman 0 döndürürsem ... her şeyin arkasında hiçbir ipucu yoktur) - Arayanın bu iletişimle ilgili kuralları var mı? (Tek bir değerin herhangi bir bilgi temsiline izin vermeyen bir kural olmadığını unutmayın)

Bu yanıtların her ikisi de hayır ise, muhtemelen iyi çözüm ana dönüş ifadesini hiç yazmamaktır. (Ve derleyicinin hedefe göre çalıştığına karar vermesine izin verin).

Hiçbir kural mevcut değilse 0 = başarı durumların çoğunu karşılar (ve sembollerin kullanılması, eğer bir kural ortaya koyarlarsa sorunlu olabilir).

Kurallar yürürlükteyse, onlarla tutarlı olan sembolik sabitlerin kullanıldığından emin olun (ve platformlar arasında değer tutarlılığını değil, kural tutarlılığını sağlayın).


4

Sayısız çıkış durumu döndürebilecek bir kod yazmaya başladığınızda #define, hepsini yazmaya başlıyorsunuz . Bu durumda EXIT_SUCCESS" sihirli sayı " olmama bağlamında anlamlıdır . Bu, kodunuzu daha okunaklı hale getirir çünkü diğer her çıkış kodu olacaktır EXIT_SOMETHING. Basitçe bittiğinde geri dönecek bir program yazarsanız return 0, geçerli ve muhtemelen daha temizdir çünkü karmaşık bir dönüş kodu yapısı olmadığını gösterir.


0

Bir programdan geri döndüğünüz şey sadece bir sözleşmedir.

Hayır, "EXIT_SUCCESS" in olmayacağı herhangi bir durum düşünemiyorum "0" .

Şahsen, "0" öneririm.

BENİM NACİZANE FİKRİME GÖRE...


1
10 yıldır C ++ programlama yapıyorum ve 0'ın dönüş değerleri açısından başarı mı yoksa başarısızlık mı olduğunu hala hatırlayamıyorum.
lahjaton_j

@lahjaton_j Anlıyorum. Bunun sezgiye aykırı olduğu için olduğunu düşünüyor: 0yanlıştır ve birçok işlev 0başarısız olduğunda / hiçbir şey yapmadığında geri döner .
anlam meseleleri


-5

Bazı derleyiciler bununla ilgili sorunlar yaratabilir - bir Mac C ++ derleyicisinde EXIT_SUCCESS benim için iyi çalıştı ama bir Linux C ++ derleyicisinde EXIT_SUCCESS'in ne olduğunu bilmek için cstdlib eklemem gerekiyordu. Bunun dışında bir ve aynılar.


Bir Mac'te EXIT_SUCCESS'in cstdlib dahil edilmeden çalıştığını kastettim.
Ambidextrous

4
Eğer EXIT_SUCCESSikisinden biri dahil olmadan çalışmış <stdlib.h>veya <cstdlib>bazı diğer başlık doğrudan veya dolaylı olarak tanımladığı olmalı. C ++ 'da, #includediğer standart başlıklara giden standart üstbilgiler yaygındır . Eğer bu hatasız derleme yapıyorsa: int main() { return EXIT_SUCCESS; }derleyiciniz muhtemelen hatalı.
Keith Thompson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.