为什么c程序在系统调用失败时不向stderr打印错误信息?

Why doesn't c program print error message to stderr when system call fails?

下面是一段简单的 C 代码:

#include <stdio.h>

int main(void) {
  FILE *fd = fopen("nothing", "r");
  // perror("fopen");
  return 0;
}

它什么都不打印,但是如果 perror("fopen") 没有注释,它会打印

fopen: No such file or directory

根据 perror 的手册页

When a system call fails, it usually returns -1 and sets the variable errno to a value describing what went wrong.

No such file or directory对应errno = 2

因为stderr是无缓冲的,好像只有在调用perror时,才会将错误信息写入stderr,为什么c程序会隐式忽略错误(errno 已修改)而不是立即将其写入 stderr?

补充问题... 还有其他方法可以触发stderr的写作吗?我们是否总是必须触发它 'manually' 或者在某些情况下 c 程序可以 'automatically' 使它像 java 抛出 运行 时间异常?

系统 and/or 库调用在出现错误时不会自动打印消息。这取决于你。这些函数将做的是 return 一个特定的值来指示错误,并设置 errno 来指示特定的错误。然后就可以用perror打印当前值errno.

对应的错误字符串

fopen的情况下,如果调用失败则returns NULL。所以你需要检查它是否这样做,如果是这样使用 perror 打印消息。

FILE *fd = fopen("nothing", "r");
if (fd == NULL) {
    perror("fopen failed");
}

这样做可以让您更好地控制您的程序。例如,在某些情况下,您可能希望文件 not 存在,因此无法打开文件不是错误,因此在这种情况下您不想打印错误。

无法打开 不存在的文件 不是 "system error",- 成功打开不存在的文件将是一个错误!

使用 fopen() 来测试文件是否存在可能是故意行为 - 在这种情况下您真的不想向 stderr 报告。

标准库不会向stderr报告,所有此类输出都必须明确编码。您的 OS 可能会在发生某些致命错误(例如段错误)时向 stderr 报告,但这是真正的 系统错误 ,而不仅仅是正常和要求的行为。