ฉันควรส่งคืน EXIT_SUCCESS หรือ 0 จาก main ()?


125

เป็นคำถามง่ายๆ แต่ฉันเห็นคำตอบที่ขัดแย้งกันอยู่เรื่อย ๆ : กิจวัตรหลักของโปรแกรม 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/…
Blastfurnace

2
คำตอบเกี่ยวกับ C90 นี้ถอดความจากมาตรฐาน0และEXIT_SUCCESSตีความว่าเป็นความสำเร็จ
ta.speot.is

ฉันจะตอบกลับที่นี่เพราะฉันรู้สึกว่าจะมีใครอ่านเรื่องนี้อีกในอนาคต โดยทั่วไปมีหลายกระบวนทัศน์ว่า "C ที่ถูกต้อง" มีลักษณะอย่างไร กระบวนทัศน์บางอย่างชอบใช้ตัวอักษรมากกว่ามาโครตัวอย่างเช่นแทนที่จะส่ง NULL เป็นอาร์กิวเมนต์อาจส่งผ่าน (const char *) 0 เพื่อระบุว่าไม่ใช่แค่โมฆะ แต่ถ้าไม่ใช่โมฆะควรเป็น ตัวชี้อักขระคงที่ กระบวนทัศน์อื่น ๆ ชอบที่จะเป็นประเภทไม่เชื่อเรื่องพระเจ้าและเมื่อใช้ประเภทมาโครพวกเขาสามารถหลีกเลี่ยงความจำเป็นในการเปลี่ยน codebase เมื่อสิ่งต่างๆเปลี่ยนแปลงไปอย่างสิ้นเชิง ตัวอย่างเช่น -
Dmitry

@Dmitry <continued> คำจำกัดความประเภท Windows API ไม่ถูกต้องในแพลตฟอร์มรุ่นใหม่ ๆ แต่เนื่องจากเป็นมาโครจึงมีวิธีง่ายๆในการเปลี่ยนประเภททั้งหมดเป็นประเภทที่ใช้งานได้โดยการกำหนดมาโครใหม่และประเภทเหล่านี้ส่วนใหญ่ปรับขนาดตามคำจำกัดความ (เช่น int แตกต่างกันในแพลตฟอร์มที่แตกต่างกัน) ในการสรุปให้ใช้สิ่งต่างๆเช่น EXIT_SUCCESS หากรหัสส่งคืนมีความสำคัญและอาจมีการเปลี่ยนแปลงในอนาคตมิฉะนั้นการส่งคืน 0 อาจดูเหมือนเป็นตัวเลขวิเศษ แต่ก็ยังคงเป็นแบบแผนมาตรฐานที่ถูกต้อง รหัสข้อผิดพลาดเป็นส่วนใหญ่สำหรับโปรแกรมที่จะไปป์หมายเลขผลลัพธ์จากหนึ่งไปยังอีก -
Dmitry

@Dmitry <continued> การใช้รหัสข้อผิดพลาดในการดีบักโปรแกรมของคุณค่อนข้างอ่อนแอเนื่องจากหากส่งคืนค่าเป็น 0 ข้อมูลก็ค่อนข้างไร้ประโยชน์ยกเว้นในบางกรณีเมื่อมีข้อผิดพลาดที่ไม่ได้จัดการที่ยังไม่ได้จัดการในโปรแกรมที่สามารถทำให้โปรแกรมหยุดทำงานได้อย่างเงียบ ๆ และคุณต้องการ เพื่อตรวจสอบว่าส่งคืนตามปกติ (0) หรือเกิดข้อผิดพลาดแบบไม่โต้ตอบ การส่งคืนหมายเลขมีประโยชน์มากกว่าสำหรับการส่งท่อ 0..255 จากโปรแกรมหนึ่งไปยังอีกโปรแกรมหนึ่งโดยพิจารณาจากอินพุตของพวกเขามิฉะนั้นก็ไม่มีเหตุผลที่จะต้องพิจารณา: ส่งคืน 0 หรือใช้หลักที่คอมไพล์ไว้ล่วงหน้าที่แทรกการเรียก "init" ที่เป็นโมฆะไม่ให้มองเห็น รบกวนคุณด้วยผลตอบแทนที่ไร้ประโยชน์
Dmitry

คำตอบ:


152

EXIT_FAILUREไม่ว่าจะในคำสั่ง return ใน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อย่างชัดเจน (แต่อย่างน้อยใน C ฉันถือว่าชัดเจนreturn 0;เป็นสไตล์ที่ดีกว่า)

(มีคนถามเกี่ยวกับ OpenVMS ฉันไม่ได้ใช้มันมานานแล้ว แต่ในขณะที่ฉันจำได้ว่าค่าสถานะแปลก ๆ มักแสดงถึงความสำเร็จในขณะที่ค่าแม้กระทั่งแสดงถึงความล้มเหลวการใช้งาน C 0จะจับคู่1เพื่อreturn 0;แสดงว่าการยุติสำเร็จค่าอื่น ๆ จะถูกส่งไปโดยไม่เปลี่ยนแปลง ดังนั้นreturn 1;ยังบ่งบอกถึงการยุติที่สำเร็จEXIT_FAILUREจะมีค่าคู่ที่ไม่ใช่ศูนย์)


@KeithThompson คุณช่วยชี้แจงคำตอบของคุณเกี่ยวกับ VMS (OpenVMS?) ได้ไหม ไม่ชัดเจนความสัมพันธ์ EXIT_SUCCESS / EXIT_FAILURE กับ 0 และ 1 ฉันจะอธิบายค่าคี่ / คู่แทน
malat

@malat: คุณใช้ VMS จริงหรือ?
Keith Thompson

ไม่ไม่เคยใช้ ผมกำลังมองหาคำตอบที่เป็นที่ยอมรับตั้งแต่วิกิพีเดียใช้ถ้อยคำที่แตกต่างกัน
malat

1
@Rhymoid: ระบุโดย C ไม่ใช่ POSIX
Keith Thompson

1
@DeanP: 0และEXIT_SUCCESSไม่รับประกันว่าจะมีค่าเท่ากัน (ฉันพูดถึงสิ่งนั้นในคำตอบของฉัน) แต่ทั้งคู่แสดงถึงการยุติที่ประสบความสำเร็จ EXIT_SUCCESSจะดีกว่าในทางโวหารหากคุณใช้EXIT_FAILUREด้วย แต่exit(0)ก็โอเค
Keith Thompson

25

ไม่เป็นไร. ทั้งสองอย่างเหมือนกัน

คำพูดมาตรฐาน C ++:

ถ้าค่าของสถานะเป็นศูนย์หรือ EXIT_SUCCESS รูปแบบที่กำหนดโดยการนำไปใช้งานของสถานะการยุติที่สำเร็จจะถูกส่งกลับ


12
มันไม่สำคัญกับคอมไพเลอร์ แต่มันอาจมีความสำคัญตามสไตล์
celtschk

2
@celtschk: เรื่องของสไตล์คือการรับรู้ตามที่รู้จักกันในชื่อ Non Standardized ดังนั้นจึงไม่นับเป็นความแตกต่างคุณสามารถเปรียบเทียบแอปเปิ้ลกับแอปเปิ้ลเท่านั้นไม่ใช่แอปเปิ้ลกับลูกแพร์
Alok Save

3
EXIT_SUCCESS == 0ไม่มีการรับประกันว่าเป็น ในทางกลับกันไม่มีเหตุผลที่ดีที่จะไม่เป็นเช่นนั้น
Keith Thompson

@KeithThompson: ทำไมไม่มีการรับประกันว่า EXIT_SUCCESS == 0. ? กรุณาอธิบายให้ชัดเจนยิ่งขึ้น
Destructor

2
@PravasiMeet: ระบบอาจมีค่ามากกว่าหนึ่งที่บ่งบอกถึงความสำเร็จ
Keith Thompson

11

0 คือเลขวิเศษตามนิยาม EXIT_SUCCESS เกือบจะเท่ากับ 0 อย่างมีความสุขเพียงพอ แล้วทำไมไม่เพียงแค่กลับ / ออก 0?

ออก (EXIT_SUCCESS); มีความหมายชัดเจนมาก

ออก (0); ในทางกลับกันมีการตอบโต้ในบางวิธี คนที่ไม่คุ้นเคยกับพฤติกรรมของเชลล์อาจคิดว่า 0 == false == ไม่ดีเช่นเดียวกับการใช้ 0 ใน C แต่ไม่ - ในกรณีพิเศษนี้คือ 0 == success == good สำหรับนักพัฒนาที่มีประสบการณ์ส่วนใหญ่จะไม่เป็นปัญหา แต่ทำไมต้องเดินทางไปหาผู้ชายคนใหม่โดยไม่มีเหตุผล?

tl; dr - ถ้ามีค่าคงที่ที่กำหนดไว้สำหรับจำนวนเวทย์มนตร์ของคุณแทบจะไม่มีเหตุผลเลยที่จะไม่ใช้ค่าคงที่ตั้งแต่แรก ค้นหาได้มากขึ้นมักจะชัดเจน ฯลฯ และไม่เสียค่าใช้จ่ายใด ๆ


ฉันคิดว่าความคิดเห็นของคุณเกี่ยวกับคนที่คาดหวังว่า 0 จะไม่ดีโดยอัตโนมัตินั้นไม่เหมาะสม API จำนวนมากใช้ 0 เพื่อความสำเร็จและไม่ใช่ 0 สำหรับความล้มเหลวแม้ใน stdlib เช่น STDLIB ( fclose(), setvbuf(), ... ), POSIX ( listen(), pthread_create(), pipe(), ... ) และอีกมากมายหลายห้องสมุดอื่น ๆ (เช่น OpenGL [ glGetError()] zlib [ deflate()/ inflate()/ ... ], SDL [ SDL_CreateWindowAndRenderer()/ ... ] และ มากกว่า).
Tim Čas

2
แน่นอนว่ามีกรณีอื่น ๆ ที่ใช้ 0 สำหรับ 'ความสำเร็จ' แต่เขาพูดถูกว่ามันสับสน
พอลวินทซ์

10

นี่คือเรื่องราวที่ไม่มีวันสิ้นสุดซึ่งสะท้อนให้เห็นถึงขีด จำกัด (ตำนาน) ของ

สิ่งที่โปรแกรมควรส่งคืนเพื่อบ่งชี้ "ความสำเร็จ" ควรกำหนดโดยผู้ที่ได้รับค่า (ระบบปฏิบัติการหรือกระบวนการที่เรียกใช้โปรแกรม) ไม่ใช่ตามข้อกำหนดภาษา

แต่โปรแกรมเมอร์ชอบเขียนโค้ดด้วยวิธี "แบบพกพา" และด้วยเหตุนี้พวกเขาจึงคิดค้นแบบจำลองของตัวเองสำหรับแนวคิด "ระบบปฏิบัติการ" ที่กำหนดค่าเชิงสัญลักษณ์เพื่อส่งกลับ

ตอนนี้ในสถานการณ์แบบกลุ่มต่อกลุ่ม (หลายภาษาใช้ในการเขียนโปรแกรมไปยังระบบต่างๆ) ความสอดคล้องระหว่างแบบแผนภาษาสำหรับ "ความสำเร็จ" และระบบปฏิบัติการ (ซึ่งไม่มีใครสามารถให้สิทธิ์เหมือนกันได้เสมอไป) ได้รับการจัดการโดยการใช้งานไลบรารีเฉพาะสำหรับแพลตฟอร์มเป้าหมายเฉพาะ

แต่ - น่าเสียดาย - แนวคิดเหล่านี้ซึ่งไม่ชัดเจนในเวลาที่ใช้ภาษา C (ส่วนใหญ่จะเขียนเคอร์เนล UNIX) และ Gigagrams ของหนังสือที่เขียนโดยพูดว่า "return 0 หมายถึงความสำเร็จ" เนื่องจากเป็นจริงบน OS ที่ เวลานั้นมีคอมไพเลอร์ C

จากนั้นเป็นต้นมาไม่เคยมีการกำหนดมาตรฐานที่ชัดเจนว่าควรจัดการกับการติดต่อดังกล่าวอย่างไร C และ C ++ มีคำจำกัดความของ "return values" แต่ไม่มีใครให้การแปล OS ที่ถูกต้อง (หรือดีกว่า: ไม่มีเอกสารประกอบคอมไพเลอร์พูดอะไรเกี่ยวกับเรื่องนี้) 0 หมายถึงความสำเร็จหากเป็นจริงสำหรับ UNIX - LINUX และ - ด้วยเหตุผลอิสระ - สำหรับ Windows เช่นกันและสิ่งนี้ครอบคลุม 90% ของ "คอมพิวเตอร์สำหรับผู้บริโภค" ที่มีอยู่ซึ่งโดยส่วนใหญ่แล้วจะไม่คำนึงถึงค่าที่ส่งคืน (ดังนั้นเราจึงสามารถ พูดคุยกันมาหลายทศวรรษแล้วไม่มีใครจะสังเกตเห็น!)

ในสถานการณ์นี้ก่อนที่จะตัดสินใจให้ถามคำถามเหล่านี้: - ฉันสนใจที่จะสื่อสารบางอย่างกับผู้โทรเกี่ยวกับที่มีอยู่หรือไม่ (ถ้าฉันส่งคืน 0 เสมอ ... ไม่มีเงื่อนงำเบื้องหลังทุกอย่าง) - ผู้โทรของฉันมีการประชุมเกี่ยวกับการสื่อสารนี้หรือไม่? (โปรดทราบว่าค่าเดียวไม่ใช่แบบแผนซึ่งไม่อนุญาตให้นำเสนอข้อมูลใด ๆ )

หากคำตอบทั้งสองข้อนี้ไม่ใช่ทางออกที่ดีก็คืออย่าเขียนข้อความส่งคืนหลักเลย (และปล่อยให้คอมไพเลอร์ตัดสินใจในส่วนที่เกี่ยวกับเป้าหมายกำลังทำงานอยู่)

หากไม่มีการประชุมใด ๆ 0 = ความสำเร็จเป็นไปตามสถานการณ์ส่วนใหญ่ (และการใช้สัญลักษณ์อาจเป็นปัญหาได้หากพวกเขาแนะนำการประชุม)

หากมีการจัดรูปแบบให้แน่ใจว่าได้ใช้ค่าคงที่เชิงสัญลักษณ์ที่สอดคล้องกัน (และตรวจสอบให้แน่ใจว่ามีการเชื่อมโยงกันตามแบบแผนไม่ใช่การเชื่อมโยงกันของค่าระหว่างแพลตฟอร์ม)


4

เมื่อคุณเริ่มเขียนโค้ดที่สามารถส่งคืนสถานะการออกได้มากมายคุณจะเริ่ม#define'ing ทั้งหมด ในกรณีนี้มีEXIT_SUCCESSเหตุผลในบริบทของการไม่ใช่ " เลขวิเศษ " นี้จะทำให้รหัสของคุณอ่านได้มากขึ้นเพราะทุกรหัสทางออกอื่น ๆ EXIT_SOMETHINGจะ หากคุณเพียงแค่เขียนโปรแกรมที่จะส่งคืนเมื่อดำเนินการเสร็จแล้วreturn 0ก็ใช้ได้และอาจจะสะอาดกว่าเพราะแสดงว่าไม่มีโครงสร้างโค้ดส่งคืนที่ซับซ้อน


0

สิ่งที่คุณกลับมาจากโปรแกรมเป็นเพียงการประชุม

ไม่ฉันไม่สามารถนึกถึงสถานการณ์ใด ๆ ที่ "EXIT_SUCCESS" จะไม่เกิดขึ้นเป็น "0"

โดยส่วนตัวผมขอแนะนำ "0"

IMHO ...


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
ฉันสงสัยอย่างมากว่ามันทำให้โค้ดของคุณพกพาได้มากหรือน้อย
Benjamin Lindley

9
ไม่มันจะไม่ มาตรฐานรับประกันว่า 0 และEXIT_SUCCESSทั้งคู่แสดงถึงการยุติที่ประสบความสำเร็จ
Keith Thompson

-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; }คอมไพเลอร์ของคุณน่าจะเป็นบั๊กกี้
Keith Thompson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.