By default, C++ streams (cin, cout) are synchronized with C streams (stdin, stdout). This allows mixing C and C++ style I/O. I am trying to understand what this means in practice regarding flushing. Consider the following programs:
#include <cstdio>
#include <iostream>
#include <thread>
int main() {
printf("Hello");
std::cout << std::flush;
std::this_thread::sleep_for(std::chrono::seconds(2));
return 0;
}
and
#include <cstdio>
#include <iostream>
#include <thread>
int main() {
std::cout << "Hello";
fflush(stdout);
std::this_thread::sleep_for(std::chrono::seconds(2));
return 0;
}
In both cases, output appears immediately, even though I thought cout << flush should only flush cout and fflush(stdout) should only flush printf. Why does std::cout << flush flush printf output and why does fflush(stdout) flush std::cout output?
std::cout has a stream buffer that behaves like a std::filebuf over stdout ([iostream.objects.overview]). Similarly, the other streams have a buffer that acts like a std::filebuf or std::wfilebuf over stdout/stdin/stderr.
std::cout << std::flush; calls std::flush(std::cout);. std::flush(std::cout) calls std::cout.flush(). std::cout.flush() calls std::cout.rdbuf()->pubsync() ([ostream.unformatted]).
.rdbuf() is a std::streambuf object that behaves like a std::filebuf. ->pubsync() just calls the most derived ->sync(), which for std::filebuf will write any buffered characters (which there won't be if the streams are synced) then calls fflush(file) on the held std::FILE* file ([filebuf.virtuals]).
So std::cout << std::flush; will have the same effect as std::fflush(stdout), since the stream buffer for std::cout just defers to a held std::FILE* that is stdout.
Note that when the standard streams are synchronised, their stream buffer will not actually buffer any characters. Any write std::cout.put(c) will immediately call std::fputc(stdout, c) ([ios.members.static]), so if you flush using the C api the characters will already have been written to the C streams.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With