这是使用strerror_r的正确方法吗?

时间:2013-02-21 17:06:14

标签: c++ errno

我在这样的代码中为线程安全性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的线程安全打印。使用128似乎也可以,因为man页面说strerror_r将返回指向不可变静态字符串的指针(可能是空终止)或者在用空值填充后指向buf的指针终结者无论大小......只是不确定这个简单的包装器是否有问题(潜在的错误)

1 个答案:

答案 0 :(得分:3)

我不理解你想要使用它的完整上下文(特别是struct MyErrno的作用是什么,StreamErrno是什么,因为你的operator<<定义适用于未使用的类型sockaddr_in的值。)

但是,一般而言,这不是一种使用errno的安全方式,尽管使用strerror_r是一种非常安全的方法。

问题是你很可能在这样的上下文中使用它:

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

也就是说,系统调用之间可能会有一些系统调用(输出字符串“Something bad occurred”),系统调用失败,在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
            << ...
}