【问题标题】:GNU strerror_r buffer meaningGNU strerror_r 缓冲区含义
【发布时间】:2017-05-14 11:01:00
【问题描述】:
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

【问题讨论】:

    标签: c glibc strerror


    【解决方案1】:

    引用man page强调我的

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

    所以很有可能buf 未被使用,如果buf 未被使用,buflen 无关紧要。

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

    【讨论】:

    • 那么,它只用于Unknown error errno 消息吗?而且我仍然可以使用返回值来访问它,对吧?
    • 它可能仅在需要时使用。 _r 后缀通常表示可重入,因此可能会在存在线程的情况下使用它。
    • 我的意思是 buffer memory “它使用”,而不是 strerror_r
    • 线程的存在没有任何改变:cpp.sh。我只是想知道:是否有任何缓冲区使用比Unknown error %int% 更长的消息,或者我可以使用char buf[30] 来不截断任何内容?
    【解决方案2】:

    正如您在 cmets 中注意到的,bufbuflen 参数仅在您传递无效 errnum、负数或未知 errno 时使用 值。 the source code of the function 确认了这一点。

    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 实现使用的大小完全相同(即线程不安全)。另见the related answer and the comment to it

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

    【讨论】:

    • 你能指出,为什么32字节不够? "Unknown error %d" 永远不会超过它...哦,关键是localized string。在其他地区可能会更长一些。我说的对吗?
    • 是的。例如,如果您设置俄语语言环境,则此字符串将被翻译为"Неизвестная ошибка",在 UTF-8 编码中占用 35 个字节。还要添加 11 个符号(int 的最小值至少包含 10 个数字和减号,但 __strerror_r 为此保留 20 个字符)。
    猜你喜欢
    • 2015-02-27
    • 2021-09-18
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多