gpt4 book ai didi

c++ - 在 Alpine Linux 上错误地声明了 strerror_r

转载 作者:IT王子 更新时间:2023-10-29 01:11:11 26 4
gpt4 key购买 nike

我正在使用 strerror_r在日志记录辅助函数中。如手册页所述,此函数有两个版本。 POSIX 版本返回一个 int。 GNU 版本返回一个字符串 (char*)。

因此,为了让我的 C++ 代码更具可移植性,我有一段与此类似的代码:

    char buffer[1000];
int size = 1000;
int result = 0;
char* msg = buffer;
buffer[0] = '\0';
#ifdef _GNU_SOURCE
msg = strerror_r(err, buffer, size);
#else
result = strerror_r(err, buffer, size);
if (result != 0)
{
sprintf(buffer, "unknown error: %d", err);
}
#endif
LogToFile(msg);

在上面的代码块中,它将根据 _GNU_SOURCE 的存在使用任一版本的 strerror_r,它总是由 g++ 设置,因为 libstdc++ 需要它。在 Mac 和 Unix 的其他变体上,它将使用 POSIX 版本。

现在这段代码在很长一段时间内一直运行良好,直到今天。试图在 Alpine Linux 上编译我的代码的用户今天在使用 strerror_r

的行上报告了这个编译器错误
main.cpp:16:21 error: invalid conversion from 'int' to 'char*' [-fpermissive]

映射到这一行:

#ifdef _GNU_SOURCE
msg = strerror_r(err, buffer, size);

在这个平台上的 /usr/include/string.h 处达到顶峰揭示了以下内容:

#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|| defined(_BSD_SOURCE)
...
int strerror_r (int, char *, size_t);
...
#endif

看来无论使用什么编译环境,strerror_r 的唯一声明版本是返回 int 的 POSIX 版本。这样就解释了为什么会发生错误。

在不必告诉用户他们可以手动#undef _GNU_SOURCE 或修改源代码的情况下,我该如何解决这个问题,以便代码可以继续移植?全局取消定义 _GNU_SOURCE 可能是行不通的,因为这是 C++(并且如上所述,libstdc++ 需要)。我正在尝试查看是否还有其他可以测试的宏组合,但我无法得出任何明显的结论。

最佳答案

您可以利用 C++ 函数重载:

char* check_error(int result, char* buffer, int err) {
if(result)
sprintf(buffer, "unknown error: %d", err);
return buffer;
}

char* check_error(char* result, char*, int) {
return result;
}

并且在使用中去掉条件编译:

char buffer[1000];
buffer[0] = '\0';
char* msg = check_error(strerror_r(err, buffer, sizeof buffer), buffer, err);
LogToFile(msg);

关于c++ - 在 Alpine Linux 上错误地声明了 strerror_r,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41953104/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com