我在这样的代码中为线程安全性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
的指针终结者无论大小......只是不确定这个简单的包装器是否有问题(潜在的错误)
答案 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
<< ...
}