【发布时间】:2020-05-10 23:14:10
【问题描述】:
我正在使用 Matei David 的 handy C++ wrapper for zlib,但在 macOS 上编译时出现错误(clang-1100.0.33。
include/strict_fstream.hpp:39:37: error: cannot initialize a parameter of type 'const char *' with an lvalue of type 'int'
问题出在这里:
/// Overload of error-reporting function, to enable use with VS.
/// Ref: http://stackoverflow.com/a/901316/717706
static std::string strerror()
{
std::string buff(80, '\0');
// options for other environments omitted, where error message is set
// if not Win32 or _POSIX_C_SOURCE >= 200112L, error message is left empty.
auto p = strerror_r(errno, &buff[0], buff.size());
// error next line
std::string tmp(p, std::strlen(p));
std::swap(buff, tmp);
buff.resize(buff.find('\0'));
return buff;
}
(IIUC与zlib无关,只是试图以线程安全的方式报告错误)。
如果我改成这样:
static std::string strerror()
{
std::string buff(80, '\0');
auto p = strerror_r(errno, &buff[0], buff.size());
// "fix" below
size_t length = buff.size();
std::string tmp(p, length);
std::swap(buff, tmp);
buff.resize(buff.find('\0'));
return buff;
}
我的程序编译并运行良好。
我有两个问题:
为什么clang不喜欢构造函数
std::string tmp(p, std::strlen(p));?缓冲区在函数开头声明为长度 80。为什么我们还要费心查找长度?
2的答案可能会回答这个问题,但是我的版本有问题吗?
谢谢。
【问题讨论】:
-
查看
strerror_r的文档。它有两个完全不同的版本,具有不同的返回值。你有一个返回int的。这就是您的strerror_r显然返回的内容,并且从 int 构造std::string,因为错误消息清楚地抱怨,很明显,不会有好的结果。 -
有一个叫做
strerror的ISO C(和包含的ISO C++)函数;为避免混淆,最好将此函数重命名为其他名称 -
是的,谢谢@M.M,它实际上在原始代码的命名空间中。我的代码修剪有点激进。