2
char *strerror_r(int errnum, char *buf, size_t buflen);

这些buf/buflen参数是做什么用的?

空缓冲区就像一个魅力:

char* buf = nullptr;
fprintf(stderr, strerror_r(errno, buf, 0));

此外,这个缓冲区看起来像未使用:

char buf[1024];
fprintf(stderr, "%s\n", strerror_r(errno, buf, sizeof buf)); // Correct message here
fprintf(stderr, "%s\n", buf); // Empty
4

2 回答 2

3

引用手册页强调我的

GNU-specificstrerror_r()返回一个指向包含错误消息的字符串的指针。这可能是指向函数存储的字符串的指针,也可能是buf指向某些(不可变的)静态字符串(在这种情况下buf未使用)的指针。

因此,很有可能buf未使用,如果buf未使用,buflen则没关系。

[....]如果函数将字符串存储在 中buf,则最多buflen存储字节(如果字符串buflen太小且errnum未知,则字符串可能会被截断)。[...]

于 2016-12-30T05:45:19.667 回答
1

正如您在评论中注意到的那样,仅当您传递无效的errnum、负数或未知的errno值时,才使用bufbuflen参数。函数的源代码证实了这一点。

char *
__strerror_r (int errnum, char *buf, size_t buflen)
{
  if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal
                        || _sys_errlist_internal[errnum] == NULL, 0))
    {
      /* To fill up buf with "Unknown error" localized string and to append
         digits of errnum. Nothing happens if buflen equals zero. */

      ...

      return buf;
    }

  return (char *) _(_sys_errlist_internal[errnum]);
}

关于缓冲区的容量,我认为 1024 字节就足够了。此外,它与strerror实现使用的大小完全相同(即线程不安全)。另请参阅相关答案及其评论

当然,这一切都与函数的 GNU 版本有关。XSI 兼容版本始终使用此缓冲区来复制静态字符串。

于 2017-03-06T08:14:12.513 回答