当我阅读的文档时fflush
,它说如果成功则返回 0,否则返回 EOF(我的机器上的 EOF 为 -1)。(请参阅https://man7.org/linux/man-pages/man3/fflush.3.html或https://en.cppreference.com/w/c/io/fflush)
因此我创建了以下示例:
#include<cstdio>
#include<iostream>
int main()
{
FILE* fp = std::fopen("/tmp/test", "w+");
std::fclose(fp);
std::cout << std::fflush(fp) << std::endl;
return 0;
}
g++ minimal.cpp
如果我使用或进行编译g++ -O2 -DNDEBUG minimal.cpp
,它会打印 -1。这正是我所期望的。
g++ minimal.cpp -fsanitize=address
但是,当我用或编译它时g++ minimal.cpp -fsanitize=thread
,它只打印 0。
我也可以用 clang 重现同样的问题。
怎么会这样?
我在我的 Debian 12 amd64 机器上使用了 g++-12 和 clang-15。结果始终相同(即fflush
返回 0 而不是 -1)。
根据 fflush 的文档(C99 标准中的 7.19.5.2):
这意味着如果您在未打开的文件上调用它(就像您正在做的那样),您会得到未定义的行为。
这是因为 C 标准在历史上是一个“事实上的”标准,它收集了不同实现所做的所有常见事情,而不是试图“强迫”不同的实现者实现相同的事情。因此,在很多地方(尤其是错误或极端情况),不同的实现在历史上做了不同的事情,所以标准只是说“未定义”。