errno
歴史的な理由により、Cライブラリは0に設定されません1。POSIXは、ライブラリが成功した場合に値を変更しないと主張しなくなりました。新しいLinuxのmanページにerrno.h
は、これが反映されています。
<errno.h>
ヘッダファイルには、整数型の変数を定義しerrno
、システムコールと何が悪かったのかを示すためにエラーが発生した場合に、いくつかのライブラリ関数によって設定されています、。その値は、呼び出しの戻り値がエラーを示した場合(つまり、-1
ほとんどのシステムコールから、-1
またはNULL
ほとんどのライブラリ関数から)にのみ意味があります。成功した関数は変更できますerrno
。
ANSI C理由は、委員会は、使用して、既存の慣行を採用し、標準化する方が実用的だと感じたと述べていますerrno
。
の設定を中心とするエラー報告機構errno
は、一般的には最高でも許容範囲であると見なされます。ライブラリ関数間の「病理学的結合」が必要であり、静的な書き込み可能なメモリセルを利用するため、共有可能なライブラリの構築が妨げられます。それにもかかわらず、委員会は、より野心的な何かを発明するのではなく、この既存の、しかし不十分な機械を標準化することを選びました。
ほとんどの場合、errno
設定されているかどうかを確認する以外に、エラーを確認する方法があります。errno
一部の呼び出しでは、エラーの理由を取得するために別のAPIを呼び出す必要があるため、設定されたかどうかの確認は常に信頼できるとは限りません。たとえばferror()
、fread()
またはから短い結果が得られた場合にエラーをチェックするために使用されますfwrite()
。
興味深いことに、使用例は、エラーが発生したかどうかを正しく検出するために、呼び出しの前に0にstrtod()
設定errno
する必要がある場合の1つです。strto*()
エラーが発生した場合でも有効な戻り値が返されるため、すべての文字列から数値への関数にはこの要件があります。
errno = 0;
char *endptr;
double x = strtod(str1, &endptr);
if (endptr == str1) {
/*...parse error */
} else if (errno == ERANGE) {
if (x == 0) {
/*...underflow */
} else if (x == HUGE_VAL) {
/*...positive overflow */
} else if (x == -HUGE_VAL) {
/*...negative overflow */
} else {
/*...unknown range error? */
}
}
上記のコードはstrtod()
、Linuxに記載されているの動作に基づいています。C規格では、アンダーフローが最小の正より大きい値を返すことはできず、に設定されているdouble
かどうかは実装定義2であると規定されています。errno
ERANGE
実際には、ライブラリの呼び出しの前に常に0に設定し、呼び出しが失敗したことを示した後にその値を確認することをお勧めする、広範な証明書勧告の書き込みがあります。いくつかのライブラリ呼び出しが設定されますので、これはあるコール自体が成功した場合でも、3。errno
errno
の値はerrno
プログラムの起動時には0ですが、ライブラリ関数によって0に設定されることはありません。C規格の関数の説明にerrno
使用がerrno
記載されていない場合、エラーの有無にかかわらず、ライブラリ関数呼び出しによっての値をゼロ以外に設定できます。プログラムがerrno
エラーを報告した後でのみ内容を検査することは意味があります。より正確には、errno
はerrno
、エラーを設定するライブラリ関数がエラーコードを返した後にのみ意味があります。
1.以前は、以前の呼び出しからのエラーをマスクしないようにするためだと主張しました。この主張を裏付ける証拠は見つかりません。私も偽のprintf()
例を持っています。
2.これを指摘してくれた@chuxに感謝します。参照はC.11§7.22.1.3¶10です。
3.コメントで@KeithThompsonによって指摘されました。
errno
にする場合は、いつでも自分でゼロに設定できます。