web-dev-qa-db-ja.com

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

それは簡単な質問ですが、相反する答えを見続けています。C++プログラムのメインルーチンが0またはEXIT_SUCCESSを返すべきですか?

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

または

int main(){return 0;}

それらはまったく同じものですか? EXIT_SUCCESSexit()でのみ使用する必要がありますか?

EXIT_SUCCESSは、他のソフトウェアが失敗をゼロと見なす可能性があるため、より良いオプションになると思いましたが、0を返すと、コンパイラはそれを別の値に変更できると聞きました。

101
Trevor Hickey

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

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

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

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

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

(誰かがOpenVMSについて尋ねました。長い間使用していませんでしたが、思い出すと、一般に奇数のステータス値は成功を示し、偶数の値は失敗を示します。C実装は01にマッピングし、return 0;が成功した終了を示す変更されずに渡されるため、return 1;も正常終了を示します。EXIT_FAILUREはゼロ以外の偶数値になります。)

131
Keith Thompson

それはどうでもいい事です。両方とも同じです。

C++標準引用:

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

24
Alok Save

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

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

しかし、プログラマーは「ポータブルな方法」でコードを書くのが好きであるため、返されるシンボル値を定義する「オペレーティングシステム」の概念のための独自のモデルを発明します。

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

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

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

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

この答えが両方ともいいえの場合、おそらく良い解決策は、メインのreturnステートメントをまったく書かないことです。 (そして、コンパイラーが決定することを、ターゲットに関して作業します)。

慣習が存在しない場合、0 =成功はほとんどの状況を満たします(そして、慣習を導入する場合、シンボルの使用は問題になるかもしれません)。

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

9

定義上、0はマジックナンバーです。 EXIT_SUCCESSはほぼ例外なく0に等しく、十分満足です。では、なぜ単に0を返す/終了しないのですか?

exit(EXIT_SUCCESS);意味が非常に明確です。

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

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

9
James

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

4
Phonon

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

いいえ、 "EXIT_SUCCESS" would n'tが "0"である状況は考えられません。

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

私見では...

0
paulsm4