GNU/Linux >> Linux の 問題 >  >> Linux

glibc の fclose(NULL) がエラーを返す代わりにセグメンテーション違反を引き起こすのはなぜですか?

08 引数として 17 が必要です 25 によって取得されたポインタ 、標準ストリーム 39 の 1 つ 、 47 、または 55 、または他の実装定義の方法で。 null ポインターはこれらのいずれでもないため、動作は 68 と同様に未定義です。 だろう。 NULL は特別ではない Cで;有効なポインターと等しくないことを比較することが保証されているという事実は別として、それは他の無効なポインターとまったく同じであり、それを使用すると未定義の動作が呼び出されます。>70 特別な意味があります。

さらに、エラーを返すことは有効ですが (動作はとにかく未定義であるため)、未定義の動作を隠すため、実装にとって有害な動作になります。 .未定義の動作を呼び出すことの望ましい結果は、エラーを強調表示して修正できるようにするため、常にクラッシュです。 87 のほとんどのユーザー エラーの戻り値をチェックしないでください。私は、ほとんどの人が 96 を渡すほど愚かであることに賭けます 104 まで 111 の戻り値をチェックするほどスマートではありません .人々がすべきという主張をすることができます 127 の戻り値を確認 一般に、最終的なフラッシュは失敗する可能性があるため、これは読み取り専用に開かれているファイル、または 131 の場合には必要ありません。 143 より前に手動で呼び出されました (ファイルを開いている間にエラーを処理する方が簡単なので、どちらにしても賢いイディオムです)。


156 すべき 成功した。 162 クリーンアップ コードの記述が容易になるため、成功します。

残念ながら、それは定義された方法ではありません。したがって、 176 は使用できません 移植可能なプログラムで。 (例:http://pubs.opengroup.org/onlinepubs/9699919799/ を参照)。

他の人が述べたように、間違った場所に NULL を渡した場合、通常はエラーが返されることは望ましくありません。少なくともデバッグ/テスト ビルドでは、警告メッセージが必要です。 NULL を逆参照すると、すぐに警告メッセージが表示され、プログラミング エラーを識別するバックトレースを収集する機会が得られます:)。プログラミング中に、セグメンテーション違反は発生する可能性のある最良のエラーです。 C にはもっと微妙なエラーがたくさんあり、デバッグに時間がかかります...

エラー リターンを悪用して、プログラミング エラーに対する堅牢性を高めることができます。ただし、ソフトウェアのクラッシュによってデータが失われるのではないかと心配している場合は、まったく同じことが起こる可能性があることに注意してください。ハードウェアの電源が失われた場合。これが自動保存機能を備えている理由です (Unix テキスト エディターは ex や vi のような 2 文字の名前を持つため)。一貫性のない状態で継続するよりも、ソフトウェアが目に見えてクラッシュする方が望ましいでしょう.


マニュアル ページで説明されているエラーは、プログラミング エラーではなくランタイム エラーです。 183 だけを渡すことはできません ポインターを期待する任意の API に挿入し、その API が適切な処理を行うことを期待します。 194 を渡す データへのポインターを要求することが文書化されている関数へのポインターはバグです。

関連する質問:C または C++ のいずれかで、ポインタ パラメータを NULL/nullptr に対してチェックする必要がありますか?

その質問に対する回答の 1 つに対する R. のコメントを引用するには:

<ブロック引用>

...動作環境の例外的な状態 (fs フル、メモリ不足、ネットワーク ダウンなど) から発生するエラーとプログラミング エラーを混同しているようです。前者の場合、もちろん、堅牢なプログラムはそれらを適切に処理できる必要があります。後者では、堅牢なプログラムはそもそもそれらを経験できません。


Linux
  1. Apache2 configtestが失敗しました:セグメンテーション違反(コアダンプ)[解決済み]

  2. Gpartedエラー–セグメンテーション違反(コアダンプ)?

  3. C++ エラー:'clock_gettime' および 'clock_settime' への未定義の参照

  1. connect() が EADDRNOTAVAIL を返すのはなぜですか?

  2. セグメンテーション違反を見つける最も簡単な方法

  3. 一部のカーネル プログラマーが単純な while ループの代わりに goto を使用するのはなぜですか?

  1. 致命的なエラーを返す git add:外部リポジトリ エラー

  2. Bash で eval を避ける必要があるのはなぜですか? 代わりに何を使用する必要がありますか?

  3. Linux / Apache Web サーバー セグメンテーション エラーの警告