2013-02-21 185 views
1

我提供一个C++包装的线程安全的strerror_r在这样的代码:这是使用strerror_r的正确方法吗?

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因为手册页说strerror_r将返回一个指向不可变静态字符串的指针(大概是空终止),或者在用空终止符填充它后指向buf,而不管大小如何不知道这个简单的包装有什么问题(可能是越野车)

+0

你有这个代码的一个具体问题? – 2013-02-21 17:28:31

回答

3

我不明白你想要使用它的完整上下文(特别是什么是结构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) 
      << ... 
} 

也就是说,有可能是系统之间的一些系统调用(输出字符串“一些不好的事”)呼叫失败,在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 
      << ... 
} 
相关问题