为什么 glibc 中不推荐使用“sys_errlist”?

问题描述 投票:0回答:2

sys_errlist
是一个方便的数组,可以获取静态
errno
描述。它的替代方案是
strerror_r
函数,它有两种令人困惑的不兼容的风格。它的 GNU 版本返回
char *
,只要错误已知,它就会来自上述相同的数组,否则来自用户提供的缓冲区。符合标准的
strerror_r
版本会返回
int
,并且始终使用用户提供的缓冲区。问题是,这两个函数尽管具有完全不同的语义,但共享相同的名称,因此您基本上必须执行相当复杂的
#ifdef
检查并根据您获得的版本编写两个完全不同的代码版本。除此之外,这两个函数都比
sys_errlist
更糟糕,因为它们都要求调用者提供一个“足够大”的缓冲区来保存描述,即使 GNU 版本很少使用它,并且两个函数都不允许知道缓冲区到底应该有多大。如果您选择使用
sys_errlist
代替,您可以简单地检查是否
value >= sys_nerr
并仅在这种情况下分配缓冲区,只需通过
Unknown error %d
snprintf
放在那里,然后完成。

鉴于

strerror_r
是一个可怕的、难以理解且低效的混乱,为什么 GNU 开发人员将
sys_errlist
标记为已弃用,实际上迫使人们要么使用
strerrror_r
要么在每次编译代码时观察丑陋的警告?

c posix gnu glibc errno
2个回答
2
投票

strerror
及其亲戚是本地化的。 非本地化系统消息的有用性可能存在争议,但 glibc 的维护者遵循了主流方向(Solaris 和其他系统)。

但是:

sys_errlist
已被弃用很长一段时间了。它不是 POSIX 接口。 有些系统没有它。

进一步阅读:

这个问题已经有一段时间了,但以前的情况是某些系统没有

strerror
(请参阅 Unix 不兼容说明: 字符串和内存函数)。


0
投票

如果您遇到

strerror
问题,几乎唯一可行的解决方案是不在初始化阶段之外的运行时使用它。

  • 使用复杂的平台检查来确定可用的内容。
  • 使用条件编译来选择合适的接口。
  • 如果静态列表不可用,程序应在开始工作时将
    strerror
    复制到您自己的静态存储中。在初始化期间,有一个短暂的时刻这些不可用。

例如nginx 是这样做的:https://trac.nginx.org/nginx/browser/nginx/src/os/unix/ngx_errno.c

© www.soinside.com 2019 - 2024. All rights reserved.