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)errnofprintf
strerrorスレッドセーフである必要はありません。それは愚かですが、それは標準です。strerror_l代わりに、POSIX 2008システムのドロップイン置換として使用できます。strerror_r古いシステムでも利用できますが、一部のシステムでは非準拠バージョンが存在するため、非常に厄介な問題があります。
perror追加さ'\n'れると思うので、フォーマットはになり"%s\n"ますか?
strerror_sは、実際にはインターフェースとしてはそれほど悪くありません。
_sジャンクを標準に取り入れることは、基本的にはMSによるゲームでした(「私たちのインターフェースを採用する場合、実際に私たちの製品があなたの標準をサポートするようにすることを検討します。」)そしてもちろん、今は彼らがフォローしていません。実際、私はこの1つのインターフェース自体は悪くないことに同意します。悪いのは、ほとんどの標準ライブラリが「安全でない」こと、および標準ライブラリの_s代わりに関数のファミリ全体を使用する必要があるという(コンパイラ警告の形式の)宣伝です。
彼らはかなり違うことをします。
に対応するperror()メッセージを印刷するために使用します。を使用して、やその他のストリームに何かを印刷します。非常に特殊な印刷機能です:stderrerrnofprintf()stderrperror()
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を使用します。