C标准库中的任何函数是否会隐式地使用 `stderr`?

7

C语言规范要求所有C程序都有三个可用的流(stream): stdoutstdinstderr

用户可以根据自己的需要使用这些流,例如:

fprintf(stdout, "lol");
fputs("oops", stderr);
fgets(buffer, 20, stdin);

C标准库中的一些函数会隐式地使用它们,例如:

printf("lol");           /* implicitly uses stdout */
puts("rofl");            /* implicitly uses stdout */
int c = getchar(buffer); /* implicitly uses stdin  */
  1. C标准库中是否有任何函数隐式使用stderr
  2. 在常见的C标准库实现中(例如Linux上的GNU glibc),是否有任何函数隐式使用stderr

4
perror()函数会将错误信息输出到标准错误流。 - MikeCAT
2
fflush(NULL) 刷新 所有 流。 - KamilCuk
@MikeCAT 写问题时,我只知道 perror(),但我想要一个“全面”的列表,可是我在网上找不到。我不想在问题中提到 perror,因为这感觉像是会影响答案 :) - Pod
1个回答

10
assert 宏和 perror 函数会写入标准错误流,abort_handler_s 函数(在可选的 Annex K 中)也是如此。

exit 函数会关闭文件并刷新流,因此它会隐式地作用于标准错误流。_Exitabort 可能会这样做;C 标准允许但不要求这样做。fflush(NULL) 刷新所有流。

C 2018 7.21.3 3 描述了输入和输出流之间的一些交互:在未缓冲的流或需要来自主机环境的字符的行缓冲流上请求输入时,那么行缓冲流将被刷新。这可能会影响标准错误流。

根据 C 2018 附录 J(可选),C 实现可以在正常程序终止时将某些浮点诊断写入标准错误流。

在 C 2018 标准中搜索“standard error stream”和“stderr”不会显示标准库中标准错误流的其他隐含使用。


1
如果mallocfree发现堆损坏,它们可以写入stderr。从共享库调用延迟解析函数可能会由于缺少符号而导致失败,这将导致加载器写入stderr - Employed Russian
@EmployedRussian:如果存在堆损坏,那么程序中的其他部分通过超出分配空间或其他错误导致未定义的行为。因此,这不是C标准特别允许mallocfree使用标准错误流的原因。必须考虑到任何未定义的行为可能会以某种方式影响任意数量的事情。同样,运行时链接和加载以及其中的错误超出了C标准范围。(我也不确定它们是否写入C的标准错误流,而不是例如Unix文件描述符2。) - Eric Postpischil
1
其中一个问题是:“GLIBC 函数是否_隐式地_使用 stderr?”我认为答案“在某些情况下,调用_任何_ GLIBC 函数可能会这样做”比“标准允许 X、Y 和 Z”更完整。 - Employed Russian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接