【问题标题】:Is this a correct way of using strerror_r?这是使用 strerror_r 的正确方法吗?
【发布时间】:2013-02-21 17:06:14
【问题描述】:

我正在为线程安全的 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 似乎也可以,因为手册页说 strerror_r 将返回一个指向不可变静态字符串的指针(可能是空终止)或在用空终止符填充它之后返回指向 buf 的指针,无论大小...只是不确定这个简单的包装器是否有问题(可能有问题)

【问题讨论】:

  • 这段代码有什么具体问题吗?

标签: c++ errno


【解决方案1】:

我不了解您想要使用它的完整上下文(特别是,struct MyErrno 的作用是什么,StreamErrno 是什么,因为您的 operator&lt;&lt; 定义适用于键入未使用的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
            << ...
}

【讨论】:

    猜你喜欢
    • 2012-05-11
    • 2018-12-31
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 2017-02-01
    相关资源
    最近更新 更多