alpine 编译c语言,c – 在Alpine Linux上错误地声明了strerror_r

在C编程中,作者遇到一个兼容性问题,其代码在Alpine Linux上编译失败,原因是strerror_r函数的GNU版本与POSIX版本不兼容。为了解决这个问题,作者提出了一种利用函数重载的方法,通过检查编译错误来选择适当的strerror_r实现,从而保持代码的可移植性。这种方法避免了用户需要手动修改源代码或定义预处理器宏。
摘要由CSDN通过智能技术生成

我在日志助手功能中使用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);

在上面的代码块中,它将使用任一版本的strerror_r,具体取决于_GNU_SOURCE的存在,它总是由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);

标签:alpine,c,linux,g

来源: https://codeday.me/bug/20190724/1523673.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值