C标准库角案例

时间:2010-07-08 18:48:07

标签: c visual-c++ stdio

以下程序是否为有效的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)时,我得到了一个 “Debug Assertion Failed”窗口,显示消息:“Inconsistent Stream Count。连续读取和写入之间的刷新”。在读取和写入之间添加fflush可以解决问题。 (这在调试版本中发生。在发布版本中,第二次写入静默失败)。

这种行为是否正确,或者这是编译器库错误?我无法找到任何描述何时读取或写入在C中是非法的规则。

1 个答案:

答案 0 :(得分:3)

C99在7.19.5.3(fopen)第6段中说:

  

当使用更新模式('+'作为上述mode参数值列表中的第二个或第三个字符)打开文件时,可以在关联的流上执行输入和输出。但是,如果没有对fflush函数的干预调用,输出不应直接跟随输入,并且输入不应直接跟随输出而不干预对文件定位功能的调用,除非输入操作遇到文件结束。

恭喜您在实践中发现了这个角落案例。库实现是完全正确的,因为你违反了上面引用的

顺便说一句,从stderr读取并不罕见。当stdinstdout被重定向且没有终端可用时,这非常有用。虽然C99不保证它是可读的,但我记得在类似POSIX的系统中有些情况已经完成了。