1. ホーム
  2. c

[解決済み] C言語ではexit()を使うべきですか?

2023-07-13 09:10:58

質問

あるのは 質問 を使用することについて exit を使うことについての質問です。答えは、主にRAIIのために、それは良いアイデアではないことを議論しています、例えば、もし exit がコード内のどこかで呼び出されると、オブジェクトのデストラクタは呼び出されなくなります。

C言語ではこのような状況はどうなのだろうかと興味がありました。C言語ではコンストラクタ/デストラクタを使用しないので、C言語では状況が異なるかもしれないと思いました。 exit を使ってもいいのでしょうか?例えば、以下のような関数がC言語で使われることがあるのを見たことがあります。

void die(const char *message)
{
    if(errno) {
        perror(message);
    } else {
        printf("ERROR: %s\n", message);
    }

    exit(1);
}

どのように解決するのですか?

よりも abort() というように exit() 関数は、C言語では "graceful"終了であると考えられています。

C11 (N1570) 7.22.4.4より/p2 終了関数 (強調)です。

exit 関数は 通常 プログラムの終了を引き起こします。

規格では7.22.4.4/p4でこうも言っています。

次に、すべてのオープンストリームで 書き込まれていないバッファードデータがあるオープンなストリームは 次に、すべての 開いているストリームは 閉じられます。 によって作成されたすべてのファイル、および tmpfile 関数 が削除されます。

また、7.21.3/p5を見る価値があります。 ファイル :

もし main 関数が元の呼び出し元に戻るか、あるいは exit 関数が呼び出された場合は 開いている全てのファイルを閉じます。 (従って、全ての出力 ストリームはフラッシュされます)。プログラム終了のための他のパス プログラム終了への他のパス、例えば abort 関数を呼び出すなど,プログラム終了への他の経路では すべてのファイルを適切にクローズする必要はありません。

しかし、以下のコメントで述べられているように、これが他のすべての リソース をカバーすると仮定することはできませんので、その場合は atexit() に頼って、それらの解放のためのコールバックを個別に定義する必要があるかもしれません。実際、それはまさに atexit() が意図していることであり、7.22.4.2/p2 に書かれているように atexit関数 :

atexit 関数が指し示す関数を登録します。 func が指す関数を登録する。 を登録します。

注目すべきは、C 標準規格では 割り当てられたストレージの持続時間 (すなわち malloc() ) があるため、特定の実装でそれがどのように行われるかを知っておく必要があります。最近のホスト指向のOSでは、システムがこれを処理することが多いようですが、それでも、以下のようなメモリデバッガを黙らせるために、自分でこれを処理したいと思うかもしれません。 Valgrind .