exit()
またはmain()
でreturn
ステートメントを使用する必要がありますか?個人的に私はreturn
ステートメントを好みます。コードを読んでいるときに他の関数やフロー制御を読んでいるような気がするからです(私の意見では)。 main()
関数をリファクタリングしたい場合でも、exit()
よりもreturn
を持つ方が良い選択のようです。
exit()
はreturn
がしない特別なことをしますか?
実際には、is違いがありますが、微妙です。 C++にはより多くの影響がありますが、違いは重要です。
main()
でreturn
を呼び出すと、ローカルにスコープされたオブジェクトのデストラクタが呼び出されます。 exit()
を呼び出すと、ローカルスコープのオブジェクトに対してデストラクタは呼び出されません!それを読み直します。 exit()
返さない。それは、私がそれを呼ぶと、「バックジーはない」ことを意味します。その関数で作成したオブジェクトは破棄されません。多くの場合、これには影響はありませんが、ファイルを閉じるような場合もあります(確実にすべてのデータをディスクにフラッシュしますか?)。
exit()
を呼び出しても、static
オブジェクトはクリーンアップされることに注意してください。最後に、abort()
を使用すると、オブジェクトは破棄されないことに注意してください。つまり、グローバルオブジェクト、静的オブジェクト、およびローカルオブジェクトにはデストラクタが呼び出されません。
リターンよりも終了を優先する場合は注意して進めてください。
http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a
別の違い:exit
は標準ライブラリ関数であるため、ヘッダーを含めて標準ライブラリとリンクする必要があります。 (C++で)説明すると、これは有効なプログラムです。
int main() { return 0; }
ただし、exit
を使用するには、インクルードが必要です。
#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }
さらに、これにより、exit
からmain
を呼び出すと、ゼロを返すのと同じ副作用があるという追加の仮定が追加されます。他の人が指摘したように、これはあなたが構築している実行可能ファイルの種類(つまり、誰がmain
を呼び出しているか)に依存します。 Cランタイムを使用するアプリをコーディングしていますか? Mayaプラグイン? Windowsサービス?ドライバー?各ケースでは、exit
がreturn
と同等であるかどうかを調べるための調査が必要です。 本当に意味するexit
のときにreturn
を使用すると、コードが混乱しやすくなります。 OTOH、あなたが本当に意味があるexit
である場合、必ずそれを使用してください。
exit
を優先する理由が少なくとも1つあります。atexit
ハンドラーのいずれかがmain
の自動ストレージ期間データを参照する場合、またはsetvbuf
またはsetbuf
を使用して標準ストリームの1つに自動ストレージ期間バッファーを割り当てる場合main
からmain
から戻ると、未定義の動作が発生しますが、exit
の呼び出しは有効です。
別の潜在的な使用法(ただし、通常は玩具プログラム用に予約されています)は、main
の再帰呼び出しでプログラムを終了することです。
Exit()は 'return'がしない特別なことをしますか?
まれなプラットフォーム用の一部のコンパイラでは、exit()
は引数をプログラムの終了値に変換しますが、main()
からの戻り値は変換せずにホスト環境に直接値を渡すだけです。
これらの場合、標準は同一の動作を必要とします(具体的には、main()
からint
- compatibleを返すことは、その値でexit()
を呼び出すことと同等です。問題は、OSごとに終了値を解釈するための規則が異なることです。多くの(多くの!)システムでは、0は成功を意味し、その他は失敗を意味します。しかし、VMSでは、奇数の値は成功を意味し、偶数の値は失敗を意味します。 main()
から0を返した場合、VMSユーザーにはアクセス違反に関する厄介なメッセージが表示されます。実際にはアクセス違反はありませんでした。これは、障害コード0に関連付けられた標準メッセージでした。
その後、ANSIが登場し、exit()
に渡すことができる引数としてEXIT_SUCCESS
とEXIT_FAILURE
を祝福しました。標準では、exit(0)
はexit(EXIT_SUCCESS)
と同じように動作する必要があるため、ほとんどの実装ではEXIT_SUCCESS
を0
に定義しています。
したがって、標準では、値0を持っているfailureコードを返す標準的な方法がないため、VMSにバインドされます。
したがって、1990年代初期のVAX/VMS Cコンパイラは、main()
からの戻り値を解釈せず、ホスト環境に値を返しました。しかし、exit()
を使用した場合、標準が要求することを行います:EXIT_SUCCESS
(または0
)を成功コードに、EXIT_FAILURE
を一般的な失敗コードに変換します。 EXIT_SUCCESS
を使用するには、hadをexit()
に渡しますが、main()
から返すことはできません。そのコンパイラのより新しいバージョンがその動作を維持したかどうかはわかりません。
次のように見えるポータブルCプログラム:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, World!\n");
exit(EXIT_SUCCESS); /* to get good return value to OS */
/*NOTREACHED*/ /* to silence lint warning */
return 0; /* to silence compiler warning */
}
余談:正しく思い出せば、終了値のVMS規則は奇数/偶数よりも微妙です。実際には、下位3ビットのようなものを使用して、重大度レベルをエンコードします。ただし、一般的に言えば、奇数の重大度レベルは成功またはその他の情報を示し、偶数の重大度レベルはエラーを示しました。
I 強く 2番目のR。プログラムが実際に終了する前にmain()
の自動ストレージが再利用されないようにするためのexit()の使用に関するコメント。 main()
のreturn X;
ステートメントは、exit(X);
の呼び出しと正確に同等ではありません。なぜなら、main()
の動的ストレージは、main()
が戻ると消滅するからです。代わりにexit()
の呼び出しが行われても消えません。
さらに、CまたはCに似た言語では、return
ステートメントは、呼び出し関数で実行が続行されることを読者に強く示唆しますが、呼び出したCスタートアップルーチンをカウントする場合、この実行の継続は通常技術的に真ですあなたのmain()
関数、それはあなたがプロセスを終了するつもりであるときに正確にyouが意味するものではありません。
結局、main()
を除く他の関数内からプログラムを終了したい場合、mustexit()
を呼び出します。 main()
でも一貫してそうすることで、コードがより読みやすくなり、コードをリファクタリングするのが誰でも簡単になります。つまり、main()
から他の関数にコピーされたコードは、shouldであるはずのreturn
ステートメントがexit()
呼び出し。
したがって、これらの点をすべて組み合わせて結論を出すと、少なくともCではreturn
ステートメントを使用して悪い習慣になりますmain()
でプログラムを終了します。
main()
の標準プロトタイプはreturn
を返すと言うので、私は常にint
を使用します。
ただし、標準の一部のバージョンではmain
の特別な処理が行われ、明示的なreturn
ステートメントがない場合は0が返されると想定しています。次のコードを考えます:
int foo() {}
int main(int argc, char *argv[]) {}
G ++はfoo()
に対してのみ警告を生成し、main
からの欠落した戻りを無視します。
% g++ -Wall -c foo.cc
foo.cc: In function ‘int foo()’:
foo.cc:1: warning: control reaches end of non-void function
Cでは、main
から戻ることは、同じ値でexit
を呼び出すこととまったく同じです。
C標準 状態のセクション5.1.2.2.3:
メイン関数の戻り値の型がintと互換性のある型である場合、メイン関数への最初の呼び出しからの戻り値は、メイン関数の戻り値としてexit関数を呼び出すことと同等ですその引数; 11)main関数を終了する}に到達すると、値0が返されます。戻り型がintと互換性がない場合、ホスト環境に返される終了ステータスは指定されていません。
C++のルールは、他の回答で述べたように少し異なります。
実際、IS main
のexit(0)
とreturn(0)
の違いは、main
関数が複数回呼び出された場合です。
次のプログラム
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
return(0);
printf("%d", main(argc - 1, argv));
}
として実行
./program 0 0 0 0
次の出力になります。
00000
しかし、これは:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc == 0)
exit(0);
printf("%d", main(argc - 1, argv));
}
引数に関係なく、何も出力しません。
誰もあなたのmain
を明示的に呼び出さないと確信している場合、それは一般的に技術的に大きな違いではありませんが、より明確なコードを維持するためにexit
はより良く見えます。何らかの理由でmain
を呼び出したい場合は、必要に応じて調整してください。
Cについて話す.