プログラムの初期化時にerrnoが0に設定され、エラーが発生する前にテストできないのはなぜですか? [閉鎖]

プログラムの初期化時にerrnoが0に設定され、エラーが発生する前にテストできないのはなぜですか? [閉鎖]

errnoヘッダーファイル変数に利用可能な資料を読み込んでいます。<errno.h>

私は読んだ:

「値が 0 の場合、プログラムにエラーがないことを示します。」 「errnoプログラムが初期化されると、開発者はゼロに設定する必要があります。」

慣例的に、私たちはerrnoエラーが発生したときにのみ変数をチェックします(例:-1を返すいくつかの関数)。

errno質問1:それでは、プログラムを開始する前に0に設定するとどうなりますか?

さらに、エラー番号をローカル変数に保存してから確認する方が良いことを読んでいます。

 if (somecall() == -1) {
      printf("somecall() failed\n");
      if (errno == ...) { ... }
      }

上記のコードでprintf()エラーが発生した場合、関数呼び出しは値を上書きする可能性があります。errnoprintf()

質問2:上記はシステムコールにも適用され、perror()エラーstrerror()も発生する可能性があります。

errnoRichard Stevensの「UNIX環境の高度なプログラミング」では、関数の戻り値がエラーの発生を示すときにのみ関数値を確認する必要があることを読んでいます。なぜか分からないのですか?

答え1

慣例的に、私たちはerrnoエラーが発生したときにのみ変数をチェックします(例:-1を返すいくつかの関数)。

errno質問1:それでは、プログラムを開始する前に0に設定するとどうなりますか?

実際には、errnoエラーが発生した状況のみを確認してください。これはerrno、エラーが発生していない場合(たとえば、ライブラリ呼び出しの実行中にエラーが発生したが回復した場合)、まだゼロ以外の値を含めることができるためです。

したがって、errno「プログラムの開始」の前にゼロに設定する必要はなく、このアドバイスに従わないでください。

詳細については、エラー番号をローカル変数に保存してから確認する方が良いことを読んでいます。

はい!printf()破壊できるというあなたの観察はerrno正しいです。その値を保存する必要がある場合は、エラーが発生したらできるだけ早くローカル変数にコピーする必要があります。

Q2:上記の説明はperror()とstrerror()にも適用されますか?どちらもシステムコールであり、エラーも発生する可能性があるためです。

perror()変更された内容は呼び出されない可能性がありますがerrno、そうである場合は、errnoその前に値をコピーするように注意する必要があります。私はそれがperror()あなたのシステムでうまく機能すると思うことができると信じています!

strerror()エラー番号をパラメータとして受け取るので心配する必要はなく、消滅しても以前のerrno値はそのまま保存されます。

errnoRichard Stevensの「UNIX環境の高度なプログラミング」では、関数の戻り値がエラーの発生を示すときにのみ関数値を確認する必要があることを読んでいます。なぜか分からないのですか?

失敗時に設定されたシステムコールとライブラリコールは、errno成功時に設定する必要がないため、以前の値を保持します。

答え2

質問1に答えるには、errnoプログラムの先頭でなぜゼロに設定するのですか?errnoある時点で、いくつかの愚か者は、以前のシステムコールが失敗したことを確認せずにプログラムを変更し、その値を使用できることです(errno失敗した場合にのみ設定され、成功した場合は0にリセットされません)。

perror()そしてstrerror()いいえライブラリ関数であるシステムコール。errno呼び出し時に元の値を維持するように注意してください。 (strerror()実際にはマクロ()である可能性があるため、#define有効な値がある場合にのみ呼び出す必要があります。)errno

関連情報