1

次のようなコードで、スレッドセーフなstrerror_rにc++ラッパーを提供しています。

struct MyErrno {};
std::ostream& operator<<(std::stream& os, const MyErrno& err)
{
    const int len = 128
    char buf [len];
    os << strerror_r(errno, buf, len);
    return os;
}

これは単なるラッパーなので、C++コードでは次のように言うことができます

<< MyErrno() << ..

errnoのスレッドセーフ印刷を使用します。strerror_rまた、マニュアルページでは、サイズに関係なく、不変の静的文字列(おそらくnullで終了)へのポインタ、またはnullターミネータを入力した後のポインタが返されるため、128を使用してもbuf問題ないようです...確かではありませんこの単純なラッパーに問題がある場合(バグがある可能性があります)

4

1 に答える 1

3

これを使用する完全なコンテキストがわかりません(特に、使用されていないタイプの値に定義が適用されるため、structの役割とはMyErrno何ですか)。StreamErrnooperator<<sockaddr_in

ただし、一般的には、これは安全な使用方法ではありませんがerrno、完全に安全な使用方法strerror_rです。

問題は、ほとんどの場合、次のようなコンテキストでこれを使用している可能性があることです。

if ((something) != OK) {
  std::cerr << "Something bad happened: "
            << (some value which causes your function to be called)
            << ...
}

つまり、失敗したシステムコールの間に何らかのシステムコール(文字列「何か悪いことが起こった」を出力)があり、値をに残してから、関数errnoでの使用が発生する可能性がerrnoあります。errnoエラーが無害であっても、システムコールが設定される可能性は十分にあります。したがって、ベストプラクティスは、の値をerrno すぐに取得することです。これは、次のようなカスタムタイプを使用するのに適した理由ですMyError

struct MyError {
  int error;
  MyError(int err) : error(err) {}
};

std::ostream& operator<<(std::ostream& os, const MyError& e) {
  // as with your function, but using `e.error` instead of `errno`
}

if ((something) != OK) {
  MyError e(errno);
  std::cerr << "Something bad happened: " << e
            << ...
}
于 2013-02-21T18:23:31.803 に答える