web-dev-qa-db-ja.com

C ++でのexit()の正しい使用法は?

データファイルを読み取り、テキストを解析し、そのデータに対して処理を行う簡単なアプリケーションを作成しました。データファイルは、私のmain()関数で開かれます。ファイルが適切に開かれなかったと判断された場合、exit()関数を使用するのは良いプログラミング習慣ですか?例えば:

if (!file.is_open() ){
     exit(1);
}

さらに、私のプログラムには、ファイル内のデータを解析するための別の機能があります。この関数はmain()によって呼び出されます。関数がデータでエラーを検出した場合、エラーメッセージを出力した後、プログラムを停止させます。このような状況では、構文解析関数内でexit()関数を使用しても問題ありませんか? main()関数に制御を戻すことなく、関数がプログラムを単独で終了できるようにするのはあまりきちんとは思えないため、この質問をしています。 (この質問がかなり明白なようであれば、私は謝罪します。私はC++とプログラミング全般に不慣れです)。

22
mahela007

関数からexitを呼び出すことは、動作が明確に定義されているという意味で「悪い」わけではありません。そうすることには根本的な問題はありません。

しかし、たとえばライブラリに終わる可能性のある関数を作成している場合、そこからexitを呼び出すことは一般に悪い習慣です:エラーを呼び出しコードに通知することははるかに良いです(特定の経由でたとえば、戻り値または例外)を呼び出して、呼び出し元のコードに処理を決定させます。 (ただし、完全に有効な場合もあります。たとえば、quit_if_file_not_foundという関数を作成している場合、ユーザーは終了を期待しています。)

あなたの場合、解析関数はおそらくexitを呼び出すべきではありません:たとえば、将来のある時点で、メインコードが最初のファイルを解析する場合に別のファイル名をユーザーに要求するようにしたい場合があります失敗しました。解析ルーチンがプログラムを終了する場合、メインコードとその関数の両方を変更する必要があります。エラー状態を通知した場合は、mainのロジックを変更するだけで済みます。

(また、エラーメッセージを出力したり、上記のようなログを記録せずにexitするだけではありません。これは、発生したコードの問題を修正する方法がわからない不満なユーザーに役立ちます。)

15
Mat

2つの側面があります。 1つは、exitを使用したい場所でプログラムを停止することを決定することです。もう1つは、exitの使用です。 マットの答え は最初のものをカバーします。

2つ目は、通常、C++ではexitが悪い選択です。その理由は、いくつかのクリーンアップ(atexitで登録された関数で、静的ストレージ期間の一部のオブジェクトのデストラクタが含まれる場合がある)がすべてではないためです(スタック上のオブジェクトのデストラクタ)そのすべてが必要な場合も、まったく必要ない場合もあります。

6
AProgrammer

exit(0)はプログラムの正常終了を示し、完全に移植可能ですが、

exit(1)(通常)は、失敗した終了を示します。ただし、その使用法は移植性がありません。

4
Manish Nagar

mainからは、exit(1)return 1に違いはありません。成功の場合は0の戻り値/終了値を使用し、失敗の場合はnon0を使用します。

サブルーチンが他の場所で使用されるライブラリルーチンである場合、何らかのリターンコードまたは例外を使用して、メインに制御を戻す必要があります。それ以外の場合は、exitまたは戻る場合、選択します。

いずれの場合でも、exitreturn code、またはexceptionのいずれかである関数の動作を文書化することをお勧めします。

2
Olaf Dietsche

exit(1)がどこから来たかによります。このexit(1)をライブラリから呼び出さないでください。自分のアプリケーションからのみ呼び出してください。

エラーコードを設定する必要がある場合は、errno(STD C変数、はい)を設定できます。

さらにC++の方法を試してみたい場合は、詳細なエラーコードとともに例外をスローできます。

2
elcuco

出口は許容されますが、メモリ内の変数を破壊しないという点で、exitとreturnステートメントを使用した場合のメモリの違いに注意することが重要だと思います。エラーが発生した場合、終了は正当化されます。そうでなければ、私はreturn文に固執するでしょう。

1
jHova