216

exit()またはreturnステートメントのみを使用する必要がありmain()ますか? 個人的にはreturn、他の関数を読んでいるように感じ、コードを読んでいるときのフロー制御がスムーズであるため、ステートメントを好みます (私の意見では)。main()また、関数をreturnリファクタリングしたい場合でも、 exit().

何もしないexit()特別なことはありますか?return

4

8 に答える 8

298

実際、違いあり ますが微妙です。C++ にはより多くの影響がありますが、違いは重要です。

を呼び出すreturnmain()、ローカル スコープのオブジェクトに対してデストラクタが呼び出されます。を呼び出すとexit()ローカル スコープのオブジェクトに対してデストラクタは呼び出されません。それを読み直してください。exit() 戻りません。つまり、一度呼んだら「裏切りなし」ということです。その関数で作成したオブジェクトは破棄されません。多くの場合、これは何の影響もありませんが、ファイルを閉じるなどの場合もあります (すべてのデータをディスクにフラッシュしたいですか?)。

staticを呼び出しても、オブジェクトはクリーンアップされることに注意してくださいexit()abort()最後に、 を使用すると、オブジェクトが破棄されないことに注意してください。つまり、グローバル オブジェクト、静的オブジェクト、ローカル オブジェクトのデストラクタは呼び出されません。

リターンよりもエグジットを優先する場合は、注意して進めてください。

http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a

于 2009-01-20T14:30:54.290 に答える
27

もう1つの違い exitは、標準ライブラリ関数であるため、ヘッダーを含めて標準ライブラリにリンクする必要があります。(C ++で)説明すると、これは有効なプログラムです。

int main() { return 0; }

ただし、使用exitするには、次のものが必要です。

#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }

exitさらに、これにより、からの呼び出しにmainはゼロを返すのと同じ副作用があるという追加の仮定が追加されます。他の人が指摘しているように、これは作成している実行可能ファイルの種類(つまり、誰が呼び出しているか)によって異なりますmain。Cランタイムを使用するアプリをコーディングしていますか?Mayaプラグイン?Windowsサービス?ドライバー?exitいずれの場合も、がと同等であるかどうかを確認するための調査が必要になりreturnます。IMHOが本当に意味するexitときに使用すると、コードがさらに混乱します。OTOH、もしあなたが本当に意味があるのなら、ぜひそれを使ってください。 return exit

于 2009-01-20T15:50:02.400 に答える
18

優先する理由が少なくとも 1 つexitあります。atexitハンドラーのいずれかが の自動ストレージ期間データを参照するmain場合、または で標準ストリームの 1 つに自動ストレージ期間バッファを使用setvbufまたはsetbuf割り当てた場合main、 から返されるとmain生成されます未定義の動作ですが、呼び出しexitは有効です。

別の潜在的な使用法 (通常はおもちゃのプログラム用に予約されています) は、 の再帰呼び出しでプログラムを終了することですmain

于 2011-05-02T12:07:32.970 に答える
5

returnの標準プロトタイプでmain()int.

とはいえ、標準の一部のバージョンでは特別な扱いがあり、明示的なステートメントmainがない場合は 0 を返すと想定されています。return次のコードがあるとします。

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
于 2009-01-20T14:17:48.780 に答える
5

プログラムが実際に終了する前に自動ストレージが再利用されるのを避けるために、exit() の使用に関する R のコメントを強く支持します。main()return X;ステートメントはmain()、 の呼び出しと正確に同等ではありませんexit(X);。これは、 の動的ストレージが戻るとmain()消えるためですが、代わりにmain()の呼び出しが行われた場合は消えませんexit()

さらに、C やその他の C に似た言語returnでは、呼び出し元の関数で実行が継続されることを読者に強く示唆するステートメントがあります。この実行の継続は通常、関数を呼び出した C スタートアップ ルーチンを数えれば技術的には正しいのですが、そうmain()ではありません。プロセスを終了することを意味するとき、まさにあなたが意味すること。

結局のところ、他の関数内からプログラムを終了したい場合は、 を呼び出すmain()必要がありexit()ます。一貫してこれをmain()行うと、コードがはるかに読みやすくなり、誰でもコードをリファクタリングしやすくなります。main()つまり、他の関数からコピーされたコードは、呼び出しであるはずreturnの偶発的なステートメントのために誤動作することはありません。exit()

したがって、これらすべての点を組み合わせると、少なくとも C では、ステートメントを使用してプログラムを終了するのは悪い習慣であるという結論になります。returnmain()

于 2011-06-26T21:29:57.463 に答える
5

exit() は、「return」がしない特別なことをしますか?

一般的ではないプラットフォーム用の一部のコンパイラでは、exit()がその引数をプログラムの終了値に変換する場合がありますが、 からの戻り値main()は変換せずに直接ホスト環境に値を渡すだけです。

標準では、これらの場合に同一の動作が要求されます (具体的には、int互換性のあるものを返すことは、その値main()で呼び出すことと同等である必要があるexit()と述べています)。問題は、OS が異なれば、終了値を解釈するための規則が異なることです。多くの (多くの!) システムでは、0 は成功を意味し、それ以外はすべて失敗を意味します。しかし、たとえば VMS では、奇数の値は成功を意味し、偶数の値は失敗を意味します。から 0 を返すmain()と、VMS ユーザーにはアクセス違反に関する厄介なメッセージが表示されます。実際にはアクセス違反はありませんでした。これは単にエラー コード 0 に関連付けられた標準的なメッセージでした。

その後、ANSI が登場し、祝福さEXIT_SUCCESSEXIT_FAILURE、引数として に渡すことができましたexit()。標準では、exit(0)は と同じように動作する必要があるとも規定されてexit(EXIT_SUCCESS)いるため、ほとんどの実装では が定義EXIT_SUCCESSされて0います。

したがって、標準では、たまたま値が 0 である失敗コードを返す標準的な方法が残っていないため、VMS で制約を受けることになります。

したがって、1990 年代初期の VAX/VMS C コンパイラは、 からの戻り値を解釈せずmain()、ホスト環境に値を返すだけでした。しかし、それを使用exit()すると、標準が要求することを実行できます。つまり、変換EXIT_SUCCESS(または0) を成功コードとEXIT_FAILURE一般的な失敗コードに変換します。を使用するにEXIT_SUCCESS、に渡す必要があり、 から戻すことはできませんでした。そのコンパイラのより新しいバージョンがその動作を保持しているかどうかはわかりません。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 ビットのようなものを使用して重大度レベルをエンコードします。ただし、一般的に言えば、奇数の重大度レベルは成功またはその他の情報を示し、偶数の重大度レベルはエラーを示します。

于 2014-12-04T18:46:59.040 に答える