12

FILE * ポインターを入力として受け取る小さなライブラリーを作成しています。

この FILE * ポインターをすぐにチェックして、セグメンテーション違反につながることがわかった場合は、シグナルを処理し、errno を設定して、正常に終了する方が正しいですか? または、何もせずに、発信者がインストールしたシグナル ハンドラーを使用しますか?

「ライブラリは決してクラッシュを引き起こしてはならない」というのが一般的な知恵のようです。しかし、私の考えでは、この特定の信号は間違いなく発信者の責任であるため、発信者からその情報を隠そうとするべきではありません。彼は、独自の方法で問題に対応するために、独自のハンドラーをインストールしている場合があります。errno を使用して同じ情報を取得できますが、SIGSEGV のデフォルトの処理は正当な理由で設定されており、シグナルを渡すことは、発信者にエラーを処理させるか、クラッシュさせてさらなる損傷から保護することにより、この哲学を尊重します。 .

この分析に同意しますか、それともこの状況で SIGSEGV を処理する説得力のある理由があると思いますか?

4

6 に答える 6

7

ハンドラーを引き継ぐことは図書館のビジネスではありません。明示的に要求されない限り、ハンドラーを攻撃することはやや不快だと思います。クラッシュを最小限に抑えるために、ライブラリは入力をある程度検証する場合があります。それ以上: ガベージ イン — ガベージ アウト。

于 2012-01-23T19:54:28.973 に答える
5

「ライブラリは決してクラッシュを引き起こしてはならない」というのが一般的な知恵のようです。

どこから取得したのかわかりません-無効なポインターを渡すと、クラッシュするはずです。どのライブラリでもそうです。

于 2012-01-23T19:52:21.747 に答える
3

NULLポインターの特殊なケースをチェックすることは合理的だと思います。しかし、それ以上に、ジャンクを渡すと、関数の契約に違反し、クラッシュします。

于 2012-01-23T19:57:42.267 に答える
2

これは主観的な質問であり、SO には適していない可能性がありますが、私の意見を述べます。

次のように考えてみてください。NUL で終わるchar *文字列を取り、そのように文書化されている関数があり、呼び出し元が NUL ターミネータなしで文字列を渡す場合、信号をキャッチして呼び出し元の手首を平手打ちする必要がありますか? それとも、クラッシュさせて、API を使用している悪いプログラマーに自分のコードを修正させるべきですか?

コードがFILE *ポインターを受け取り、ドキュメントに「すべてのオープンFILE *を渡す」とあり、閉じられたオブジェクトまたは無効化されたFILE *オブジェクトを渡す場合、それらは契約を破っています。このケースをチェックすると、ライブラリを適切に使用する人々のコードが遅くなり、そうでない人々に対応できるようになります。一方、ライブラリをクラッシュさせると、ドキュメントを読んで適切なコードを書く人々のコードが可能な限り高速に保たれます。

誰かが無効なFILE *ポインターを渡して、エラーをチェックして正しく処理することを期待できますか? それとも、やみくもに続行して、後で別のクラッシュを引き起こす可能性が高く、その場合、このクラッシュを処理することでエラーを隠すことができますか?

于 2012-01-23T19:55:30.870 に答える
1

カーネルに不正なポインタを与えてもカーネルはクラッシュしないはずですが、ライブラリはおそらくクラッシュするはずです。これは、エラー チェックを行うべきではないという意味ではありません。優れたプログラムは、不当に悪いデータに直面するとすぐに死んでしまいます。ライブラリが assert(f != NULL) を使用して bail を呼び出した方が、単純に処理して最終的に NULL ポインターを逆参照するよりもはるかに望ましいと言えます。

于 2012-01-23T19:59:22.907 に答える