C 标准库角落案例
以下程序是有效的 C 程序吗?
#include <stdio.h>
int main()
{
fwrite("x", 1, 1, stderr);
fflush(stderr);
fgetc(stderr);
fwrite("y", 1, 1, stderr);
return 0;
}
请注意,我尝试从 stderr 读取。
当我在 Visual C++ 2008 中编译它并运行它时,我得到以下输出:
xy
这是有道理的。但是,当我将 stderr 重定向到文件 (test.exe 2> foo.txt
) 时,我得到一个 “调试断言失败”窗口,显示消息:“流计数不一致。连续读取和写入之间刷新”。在读取和写入之间添加 fflush 确实可以解决问题。 (这发生在调试版本中。在发布版本中,第二次写入会默默失败)。
此行为是否正确,或者这是编译器库错误?我在任何地方都找不到任何描述 C 中读或写何时非法的规则。
Is the following program a valid C program?
#include <stdio.h>
int main()
{
fwrite("x", 1, 1, stderr);
fflush(stderr);
fgetc(stderr);
fwrite("y", 1, 1, stderr);
return 0;
}
Notice that I try to read from stderr.
When I compile it in Visual C++ 2008, and run it, I get the following output:
xy
which makes sense. However, when I redirect stderr to a file (test.exe 2> foo.txt
), I get a
"Debug Assertion Failed" window with the message: "Inconsistent Stream Count. Flush between consecutive read and write". Adding a fflush
between the read and write does fix the problem.
(This happens in debug build. In release builds, the second write silently fails).
Is this behavior correct, or is this a compiler library bug? I couldn't find anywhere any rules describing when reads or writes are illegal in C.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
C99 在 7.19.5.3 (
fopen
) 第 6 段中说:恭喜您在实践中发现了这个极端情况。库的实现是完全正确的,因为您违反了上面引用的shall。
顺便说一下,从
stderr
读取数据并不罕见。当stdin
和stdout
被重定向且没有可用终端时,这非常有用。虽然 C99 不保证它是可读的,但我记得在类似 POSIX 的系统上的一些情况实际上已经这样做了。C99 says in 7.19.5.3 (
fopen
), paragraph 6:Congratulations for discovering this corner case in practice. The library implementation is completely correct, since you violate the shall quoted above.
And by the way, it is not uncommon to read from
stderr
. This is useful whenstdin
andstdout
are redirected and no terminal is available. Although C99 doesn't guarantee it to be readable, I remember some cases on POSIX-like systems where this had actually been done.