我正在使用Matei David的handy C++ wrapper for zlib,但在macO上编译时会出错(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的回答可能会回答这个问题,但是我的版本有问题吗?
谢谢。
如果使用int strerror_r(int errnum, char *buf, size_t buflen);
,则没有适当的字符串构造函数,程序格式不正确。
如果使用char *strerror_r(int errnum, char *buf, size_t buflen);
,则程序格式正确。
编译器与您的使用无关,而是标准的C / POSIX库实现。前者是XSI中指定的POSIX扩展,后者是GNU扩展。
[如果您使用glibc(我不知道MacOS上是否可以选择该选项),则可以使用宏来控制使用哪个版本。它的文档说:
如果符合以下情况,则提供符合XSI的strerror_r()版本:(_POSIX_C_SOURCE> = 200112L || _XOPEN_SOURCE> = 600)&&! _GNU_SOURCE