main()からEXIT_SUCCESSまたは0を返す必要がありますか?


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
C90に関するこの回答は標準を言い換えたもので0ありEXIT_SUCCESS、どちらも成功と解釈されます。
ta.speot.is 2012年

他の誰かが将来これを読むと思うので、ここで応答します。基本的に、「正しいC」がどのように見えるかについては、多くのパラダイムがあります。たとえば、一部のパラダイムは、マクロよりもリテラルを使用することを好みます。たとえば、引数としてNULLを渡す代わりに、(const char *)0を渡して、それが単なるnullではないことを示しますが、それがnullではなかった場合は、定数文字ポインター。他のパラダイムはタイプにとらわれないことを好み、マクロタイプを使用することで、物事が根本的に変化したときにコードベースを変更する必要を回避できます。例えば、多くの-
ドミトリー

@Dmitry <続き> Windows APIタイプ定義は新しいプラットフォームでは正しくありませんが、マクロであるため、すべてのタイプをマクロを再定義することで機能するタイプに簡単に変更でき、これらのタイプの多くは定義によって単純にスケーリングされました(たとえば、intはプラットフォームによって異なります)。要約すると、戻りコードが重要で将来変更される可能性がある場合は、EXIT_SUCCESSなどを使用します。そうでない場合、0を返すとマジックナンバーのように見えるかもしれませんが、それでも完全に有効な標準規則です。エラーコードは主にプログラムが番号結果を別の結果にパイプするためのものです
Dmitry

@Dmitry <続き>エラーコードを使用してプログラムをデバッグすることは、0を返す場合、プログラムにサイレントブレークを引き起こす可能性のある未処理の未処理エラーがあり、それが正常に戻ったかどうか、またはサイレントエラーが発生したかどうかを確認します。数値の戻りは、入力に基づいて1つのプログラムから別のプログラムに0..255をパイプするのに便利です。それ以外の場合は、考える必要はありません。0を返すか、視覚的にではなくvoid "init"呼び出しをインライン化するプリコンパイル済みメインを使用します。無駄な戻りであなたを困らせます。
Dmitry

回答:


150

EXIT_FAILUREmainまたはへの引数としてのreturnステートメントexit()で、CまたはC ++プログラムの失敗を示す唯一の移植可能な方法です。 exit(1)たとえば、実際にVMSで正常終了を通知できます。

EXIT_FAILUREプログラムが失敗したときに使用するEXIT_SUCCESS場合は、対称性のために、成功したときに使用することもできます。

一方、プログラムがエラーを通知しない場合は、0またはを使用できますEXIT_SUCCESS。どちらも、正常に完了したことを通知することが規格によって保証されています。(EXIT_SUCCESS0以外の値になる可能性はほとんどありませんが、これまで聞いたすべての実装で0に等しいです。)

を使用0することには#include <stdlib.h>、Cまたは#include <cstdlib>C ++(をreturn呼び出すのではなくステートメントを使用する場合)では必要ないというマイナーな利点がありますexit()が、重要なサイズのプログラムの場合は、stdlibを直接または間接的に含めます。とにかく。

さらに言えば、1999年の標準以降のCおよびC ++のすべてのバージョンでmain()は、return 0;いずれにしても暗黙のうちにの終わりに到達するため、どちらを使用するか、0またはEXIT_SUCCESS明示的に使用する必要はありません。(しかし、少なくともCでは、明示的なreturn 0;方がスタイルが良いと考えています。)

(誰かがOpenVMSについて質問しました。私はそれを長い間使用していませんが、奇数のステータス値は一般に成功を示し、偶数の値は失敗を示します。Cの実装はにマップさ0れる1ため、return 0;正常終了を示します。他の値は変更されずに渡されます、return 1;つまり、正常終了を示します。EXIT_FAILUREゼロ以外の偶数値が含まれます。)


@KeithThompsonは、VMS(OpenVMS?)に関する回答を明確にしていただけませんか。0と1の関係EXIT_SUCCESS / EXIT_FAILUREは明確ではありません。代わりに奇数/偶数の値について説明します。
Malat

@malat:実際にVMSを使用していますか?
キース・トンプソン、

いいえ、使用していません。ウィキペディアで別の表現が使用されていたため、正解を探していました。
Malat

1
@Rhymoid:これはPOSIXではなくCによって指定されます。
キース・トンプソン、

1
@DeanP:0EXIT_SUCCESS同じ値であることが保証されていません(私の回答でそのことを述べました)が、どちらも正常に終了したことを示しています。EXIT_SUCCESS文体優れているならば、あなたも使っているEXIT_FAILUREが、exit(0)okです。
キース・トンプソン、

25

それは問題ではありません。どちらも同じです。

C ++標準の引用:

statusの値がゼロまたはEXIT_SUCCESSの場合、ステータスが正常に終了したことを示す、実装で定義された形式が返されます。


12
それはコンパイラーには関係ありませんが、スタイルの問題として関係するかもしれません。
celtschk 2012年

2
@celtschk:スタイルの問題は知覚ベースの非標準化であるため、差異としてカウントされません。比較できるのは、Apples with Applesだけで、Apples with Pearsは比較できません。
Alok Save

3
その保証はありませんEXIT_SUCCESS == 0。一方、そうならない理由はありません。
キース・トンプソン

@KeithThompson:なぜEXIT_SUCCESS == 0である保証がないのですか?より明確に説明してください。
デストラクタ

2
@PravasiMeet:システムには、成功を示す複数の値がある場合があります。
キース・トンプソン

11

0は、定義により、マジックナンバーです。EXIT_SUCCESSは、ほぼ普遍的に0に等しく、十分満足しています。では、なぜ単に0を返す/終了しないのですか?

exit(EXIT_SUCCESS); 意味は豊富に明らかです。

exit(0); 一方、いくつかの点で直感に反しています。シェルの動作に慣れていない人は、Cでの0の他のすべての使用と同様に、0 == false ==悪いと想定するかもしれません。ほとんどの経験豊富な開発者にとって、問題になることはありません。しかし、なぜ理由もなくまったく新しい人をつまずかせないのですか?

tl; dr-マジックナンバーに定義された定数がある場合、そもそも定数を使用しない理由はほとんどありません。より検索しやすく、多くの場合よりわかりやすく、コストもかかりません。


0が自動的に悪いと期待している人々についてのあなたのコメントは不適当だと思います。stdlibであっても、非常に多くのAPIが成功の場合は0を使用し、失敗の場合は0以外を使用します。例えばSTDLIB( fclose()setvbuf()、...)、POSIX( 、、listen() 、...)、そして多くの、多くの他のライブラリ(例えばOpenGLの[ ]、zlibの[ / / ...]、SDL [ / ...]、およびもっと)。pthread_create()pipe()glGetError()deflate()inflate()SDL_CreateWindowAndRenderer()
TimČas

2
もちろん、「成功」に0が使用されている場合もありますが、混乱するのは間違いではありません。
ポールウィンツ

10

これは、「相互運用性と移植性」の限界(神話)を反映した終わりのない話です。

プログラムが「成功」を示すために戻す必要があるのは、言語仕様ではなく、誰が値(オペレーティングシステム、またはプログラムを呼び出したプロセス)を受け取っているかによって定義される必要があります。

しかし、プログラマーは「移植可能な方法」でコードを書くことを好み、それゆえに、返されるシンボリック値を定義する「オペレーティングシステム」の概念のための独自のモデルを発明します。

さて、多対多のシナリオ(多くの言語が多くのシステムにプログラムを作成するのに役立つ)では、「成功」の言語規則とオペレーティングシステムの言語規則(常に同じであることを認めることはできない)の間の対応は、特定のターゲットプラットフォーム用のライブラリの特定の実装によって処理されます。

しかし-残念ながら-これらの概念は、C言語が展開された時点では明確ではなかった(主にUNIXカーネルを書くため)、「リターン0は成功を意味する」と書かれて書かれた書籍のギガグラム。その時はCコンパイラを持っています。

それ以来、そのような通信をどのように処理するかについて明確な標準化は行われていませんでした。CとC ++には独自の「戻り値」の定義がありますが、適切なOS変換を許可するものは誰もいません(またはそれ以上:コンパイラーのドキュメントではそれについて何も述べていません)。0は、UNIXの場合は成功、Linuxの場合は-独立した理由で-Windowsの場合も成功を意味します。これは、既存の「コンシューマーコンピューター」の90%をカバーし、ほとんどの場合、戻り値を無視します(したがって、何十年もの間議論してください、誰も気付かないでしょう!)

このシナリオの中で、決定を下す前に、次の質問をします。-自分の存在について発信者に何かを伝えたいですか?(常に0を返すだけの場合...すべての背後に手掛かりはありません)-私の発信者はこの通信について慣例を持っていますか?(単一の値は慣習ではないことに注意してください:情報表現は許可されていません)

この回答の両方が「いいえ」の場合、おそらく良い解決策は、メインのreturnステートメントをまったく記述しないことです。(そして、ターゲットに関しては、コンパイラに決定させましょう)。

規則がない場合は、0 =成功するとほとんどの状況が満たされます(規則を導入している場合、シンボルの使用は問題となる可能性があります)。

規則が整っている場合は、それらと一貫性のある記号定数を使用してください(プラットフォーム間の値の一貫性ではなく、規則の一貫性を確認してください)。


4

無数の終了ステータスを返すことができるコードを書き始めると#define、それらすべてを開始します。この場合EXIT_SUCCESS、「マジックナンバー」ではないという意味で意味があります。他のすべての終了コードがになるため、コードが読みやすくなりますEXIT_SOMETHING。完了したときに戻るプログラムを単に作成した場合、それreturn 0は有効であり、洗練された戻りコード構造がないことを示唆しているため、おそらくよりクリーンです。


0

あなたがプログラムから返すものは単なる慣習です。

いいえ、「EXIT_SUCCESS」ができない状況は考えられませんが「0」に。

個人的には「0」をお勧めします。

私見では...


1
私は10年間C ++をプログラミングしてきましたが、戻り値に関して0が成功または失敗を意味するかどうかはまだ覚えていません。
lahjaton_j 2016年

@lahjaton_jわかりました。それは直感に反するためだと思います:0falseであり、多くの関数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 ++コンパイラでは、EXIT_SUCCESSが何であるかを知るためにcstdlibを追加する必要がありました。それ以外は同じです。


MacではEXIT_SUCCESSはcstdlibを含めずに機能しました。
両手利き2012年

4
またはのEXIT_SUCCESSいずれかを含めずに機能する場合、他の一部のヘッダーで直接または間接的に定義されている必要があります。C ++では、標準ヘッダーから他の標準ヘッダーに共通です。これがエラーなしでコンパイルされる場合:コンパイラにバグがある可能性があります。<stdlib.h><cstdlib>#includeint main() { return EXIT_SUCCESS; }
キース・トンプソン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.