C standard library corner case

北战南征 提交于 2021-01-28 08:35:16

问题


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.


回答1:


C99 says in 7.19.5.3 (fopen), paragraph 6:

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function [...], and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

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 when stdin and stdout 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.



来源:https://stackoverflow.com/questions/3206913/c-standard-library-corner-case

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!