2013-08-21 10 views
5

私は、使用されているライブラリ関数のほとんどがエラー時に-1を返し、errnoをに設定したプログラムを書いています。プログラムの動作は、エラーが発生した場合に終了するようなものです。正確な出口点とプログラム(gdbを使用する例)外部からの誤差を決定するために、私は次のメソッドを使用します:errnoを常に正と仮定するのは安全ですか?

err = func_1(..arglist_1..); 
if(err != 0) 
{ 
    perror("func(..arglist..)"); 
    return ((1u << 8) | errno); 
} 
//.. 
//.. some more funcs 
//.. 
err = func_n(..arglist_n..); 
if(err != 0) 
{ 
    perror("func(..arglist_n..)"); 
    return (((unsigned)n << 8) | errno); 
} 

をここでの問題は安全な仮定です。

現実:のerrnoが常に正である:のerrnoの値は常に未満255
仮定2:errnoにextern int errno;
errno.h内部仮定1として宣言されます。

errno.hで定義されているすべてのエラー定数(EAGAINなど)に基づいて、これらの仮定は現在真です。これらは将来も真実であると仮定できますか?

P .:私はperror()に依存して終了点を決定したくありません。

+0

私はいずれかの仮定が安全であると疑う。第2のものについては、あなたは '0'が肯定的であると考えますか? – jxh

+0

IEEE Std 1003.1-2001のこの機能では、機能は設定されません(このリンクはここでは「0」を除いていません)(http://pubs.opengroup.org/onlinepubs/009695399/functions/errno.html) errnoを0に設定してください。 –

+2

標準ライブラリの関数が '0'に設定していないということは、他の誰かが' 0'に設定していないということではありません。いくつかの標準ライブラリ関数では、呼び出しが失敗したかどうかを判断する唯一の方法は、最初に 'errno'を' 0'にセットし、次に関数が何をするかを調べることです。 – jxh

答えて

12

プログラムの終了ステータスは0..255に制限されているため、これらの戻りステートメントがmain()プログラムからのものである場合、上位ビットは関係ありません。 int型とローカルストレージ 期間スレッドた

errno
変更左辺201に展開される)

C標準(ISO/IEC 9899:2011§7.5エラー<errno.h>)と言いますその値はいくつかのライブラリ関数によって正のエラー数に設定されます。

マクロerrnoは、オブジェクトの識別子である必要はありません。関数呼び出しの結果として変更可能な左辺値 に展開される可能性があります(たとえば、*errno())。

C規格では、エラーが正であると想定しています。 POSIX(IEEE STD 1003.1 2013年版)<errno.h>に対する状態:

<errno.h>ヘッダタイプintと定数式を整数に展開しなければならない以下のマクロを定義し、(下記のよう除く)異なる正の値、及びそのなければなりません#if前処理指令で使用するのに適したものでなければならない:...だから

、あなたは合理的に安全にエラー番号が正であること(生成システム)を想定することができますが、あなたのコードは、負errno(またはゼロ)を設定することができます。現時点では、POSIXシステムでは200以下のエラー番号は生成されません。したがって、255に制限されていると仮定すると、短期間では安全ですが、おそらく長期間は安全ではありません。彼らがそのように限られているべき理由はありません。

主張している「現実」は、スレッド化されていないプログラムにのみ適用されます。スレッドサポートのためにコンパイルする場合は、errnoは単にextern int errno;と宣言されておらず、いかなる場合でもerrnoを宣言してください。 を宣言する安全な方法は、<errno.h>ヘッダーを使用することです。

+0

私は私の答えを得ました、ありがとうジョナサン・レフラー。まず、彼は正しい、私はmain()でこれを行うつもりだった。次に、私は間違いを覚えていますが、私はマルチスレッドプログラムについて忘れていました。また、私は参照用に[標準の古いコピー](http://pubs.opengroup.org/onlinepubs/009695399/functions/errno.html)を使用しました。 –

+1

C89はエラー番号が正(ゼロ以外の値)であると規定しませんでした。 C99は、エラー数が正であると規定した。興味深いことに、POSIX 1997は、 "' 'ヘッダはerrnoの宣言を提供し、次のシンボリック定数にゼロ以外の値を与えます。"現在のC89(C90)規格と一致しています。 –

+0

@nishant:興味深いことに、あなたはPOSIX 2004のページに 'errno'をリンクしています。これには '肯定'は含まれていません(POSIX 2013の[' errno']ページもありません。 org/onlinepubs/9699919799/functions/errno.html))、私はPOSIX(2013)ページの ''にリンクしていますが、これについては言及しています(ヘッダのPOSIX 2004ページもそうです)。私は見ることができる場所を選んで幸運に思った。私はアシンメトリーを知らなかった。 –

関連する問題