manページを読むと、いくつかのコードは本当に違いを理解する上で私を助けていなかった-私が使用する必要があるとき、良くも- perror("...")
またはfprintf(stderr, "...")
。
manページを読むと、いくつかのコードは本当に違いを理解する上で私を助けていなかった-私が使用する必要があるとき、良くも- perror("...")
またはfprintf(stderr, "...")
。
回答:
呼び出すperror
と、解釈されたの値が得られますerrno
。これは、POSIX syscallsによって書き込まれたスレッドローカルエラー値です(つまり、すべてのスレッドがの独自の値を持っていますerrno
)。たとえば、を呼び出しopen()
、エラーが生成された(つまり、が返された-1
)場合、その後perror
すぐに呼び出して、実際のエラーを確認できます。その間に他のsyscall errno
を呼び出すperror
と、inの値が上書きされ、以前のsyscallによってエラーが生成された場合、その呼び出しは問題の診断に役立ちません。
fprintf(stderr, ...)
一方、独自のカスタムエラーメッセージを出力するために使用できます。にstderr
出力することで、エラー報告の出力が、「通常の」出力と混ざらないようにすることができますstdout
。
の呼び出しはの出力文字列値を生成するのとfprintf(stderr, "%s\n", strerror(errno))
同様であり、を介して他のカスタムエラーメッセージと組み合わせることができます。perror(NULL)
strerror(errno)
errno
fprintf
strerror
スレッドセーフである必要はありません。それは愚かですが、それは標準です。strerror_l
代わりに、POSIX 2008システムのドロップイン置換として使用できます。strerror_r
古いシステムでも利用できますが、一部のシステムでは非準拠バージョンが存在するため、非常に厄介な問題があります。
perror
追加さ'\n'
れると思うので、フォーマットはになり"%s\n"
ますか?
strerror_s
は、実際にはインターフェースとしてはそれほど悪くありません。
_s
ジャンクを標準に取り入れることは、基本的にはMSによるゲームでした(「私たちのインターフェースを採用する場合、実際に私たちの製品があなたの標準をサポートするようにすることを検討します。」)そしてもちろん、今は彼らがフォローしていません。実際、私はこの1つのインターフェース自体は悪くないことに同意します。悪いのは、ほとんどの標準ライブラリが「安全でない」こと、および標準ライブラリの_s
代わりに関数のファミリ全体を使用する必要があるという(コンパイラ警告の形式の)宣伝です。
彼らはかなり違うことをします。
に対応するperror()
メッセージを印刷するために使用します。を使用して、やその他のストリームに何かを印刷します。非常に特殊な印刷機能です:stderr
errno
fprintf()
stderr
perror()
perror(str);
に相当
if (str)
fprintf(stderr, "%s: %s\n", str, strerror(errno));
else
fprintf(stderr, "%s\n", strerror(errno));
Perror関数は、実行呼び出しを実行するのにより多くの時間を要します。ユーザー空間からカーネル空間に移動します。fprintf呼び出しはAPIからカーネルに移動します。
If you use a function that effects errno then it makes sense to use perror
.errnoに影響を与えず、単にエラーコードを返す関数を使用する場合は、fprintf(stderr、fmt、...)を使用する必要があります。たとえば、文字列が範囲外の場合、strtolはLONG_MAXまたはLONG_MINを返し、errnoをERANGEに設定します。したがって、範囲外のためにstrtolが失敗した場合は、perrorを使用します。