When does the buffer flush - c++

For cpp, I know that we have three cases to flush the buffer:
When we get std::cin
When we std::cout<<std::endl (or ohters things like endl)
When we call some function like fflush
If I am right, there is a question:
If I just write std::cout<<"hello world"; in main and run it, I could see "hello world" at the console. So, by whom and when does the buffer flush? By the compiler? Or the buffer will flush when the main finishes?

You probably want to read about std::unitbuf and std::nounitbuf. Here's a decent reference.
It might be helpful to play with some simple examples. For instance, the following code will not print Hello world ever, because there won't be automatic flushing of the output stream after any output operation:
EXAMPLE 1
#include<iostream>
int main()
{
// ----- Don't want automatic flushing ------
std::cout << std::nounitbuf;
std::cout << "Hello world";
while (1)
{
;
}
}
And this code example will indeed print Hello world, because I specified that I want the automatic flushing to be enabled:
EXAMPLE 2
#include<iostream>
int main()
{
// ----- I do want automatic flushing ------
std::cout << std::unitbuf;
std::cout << "Hello world";
while (1)
{
;
}
}
I know that the infiite while loop looks a bit silly, but it's the easiest and most portable way of pausing the code that I can think of right now (I'm sure there are better ways, though!). This way I don't get flushing because of (1) code termination, (2) destructors being called and (3) so on. It's all down to the properties of std::cout.

Stumbling on the same question, I made a little test
int main() {
printf("t");
// fflush(stdout);
while(1);
return 0;
}
It appears that without the fflush, nothing is printed out.
With the flush, my little "t" appears on the console.
So, adding to the previous response, I believe flushing doesn't happen magically, but with the help of various "events", for example when the program exits, or when the buffer is full.
This answer helped me a lot understand it.

Related

Why std::nounitbuf doesn't do anything on MSVC?

I am writing a course on modern C++ and wanting to explain how the flush operations work, so I decided to disable the automatic flush in order to write to the buffer only when std::cout is destroyed.
For that, only one standard function exists and it is the manipulator std::nounitbuf.
However, this doesn't work on MSVC.
What surprises me the most is that the alternative in C, the setvbuf function, actually allows you to deactivate the automatic flush.
It bothers me a little because I want to teach C++ and not C.
Can anyone help me? thank you!
#include <iostream>
#include <thread>
int main()
{
std::cout << std::nounitbuf; // doesn't work (output is two Hello World before the 5 seconds delay)
//setvbuf(stdout, nullptr, _IOFBF, BUFSIZ); // work (output is one Hello World, then another one after the 5 seconds)
std::cout << "Hello World" << std::endl;
std::cout << "Hello World";
std::this_thread::sleep_for(std::chrono::seconds{ 5 });
}
Why std::nounitbuf doesn't do anything?
Most probably because unitbuf flag is not set by default for standard cout stream. (Standard narrow.stream.objects requires it should be set only for cerr).
Can anyone help me?
C++ are synchronized (not buffered) with stdio streams. What you write std::cout << "something" goes straight to FILE* stdout. As it goes straight there, stdout buffering is all that matters.
Disable synchronization with stdio streams and try then. Read about std::ios::sync_with_stdio. The following works for me.
#include <iostream>
#include <thread>
int main() {
std::ios::sync_with_stdio(false);
std::cout << "Hello World" << std::endl;
std::cout << "Hello World\n";
std::this_thread::sleep_for(std::chrono::seconds{ 5 });
}
From: https://en.cppreference.com/w/cpp/io/manip/endl
In many implementations, standard output is line-buffered, and writing
'\n' causes a flush anyway, unless std::ios::sync_with_stdio(false)
was executed.
Try to remove std::endl and '\n' from the output and you will get the desired behavior. And as Marek said, std::nounitbuf is default setting for std::cout.

Why does this hang without first printing?

Why does this hang without first printing?
#include <stdio.h>
void main() {
printf("hello world");
while (1) {}
}
Because you haven't flushed the standard output. Try fflush. Even better, for C++ use...
std::cout << "hello world" << std::endl;
Separately, you'd have a better chance of it flushing itself if you added a \n, but not all implementations follow the Standard when it comes to such things.
Call fflush(stdout); after printf.
This will force the stdout buffer to be flushed and printed.

What can go wrong if cout.rdbuf() is used to switch buffer and never set it back?

The author presented this code under the title A bus error on my platform
#include <fstream>
#include <iostream>
int main()
{
std::ofstream log("oops.log");
std::cout.rdbuf(log.rdbuf());
std::cout << "Oops!\n";
return 0;
}
The string "Oops!\n" is printed to the file "oops.log". The code doesn't restore cout's streambuf, but VS2010 didn't report a runtime error.
Since log and std::cout share a buffer, that buffer will probably be freed twice (once when log goes out of scope, then once more when the program terminates).
This results in undefined behavior, so it's hard to tell the exact reason why it triggers a bus error on his machine but silently fails on yours.
Since the other answers don't mention what to do about this I'll provide that here. You need to save and restore the buffer that cout is supposed to be managing. For example:
#include <fstream>
#include <iostream>
// RAII method of restoring a buffer
struct buffer_restorer {
std::ios &m_s;
std::streambuf *m_buf;
buffer_restorer(std::ios &s, std::streambuf *buf) : m_s(s), m_buf(buf) {}
~buffer_restorer() { m_s.rdbuf(m_buf); }
};
int main()
{
std::ofstream log("oops.log");
buffer_restorer r(std::cout, std::cout.rdbuf(log.rdbuf()));
std::cout << "Oops!\n";
return 0;
}
Now when cout's buffer is replaced before cout is destroyed at the end of the program, so when cout destroys its buffer the correct thing happens.
For simply redirecting standard io generally the environment already has the ability to do that for you (e.g., io redirection in the shell). Rather than the above code I'd probably simply run the program as:
yourprogram > oops.log
Also one thing to remember is that std::cout is a global variable with all the same downsides as other global variables. Instead of modifying it or even using it you may prefer to use the usual techniques to avoid global variables all together. For example you might pass a std::ostream &log_output parameter around and use that instead of having code use cout directly.
Your program has Undefined Behavior.
The destructor of the global cout object will delete the stream buffer when going out of scope, and the same is true of log, which also owns that very same stream buffer. Thus, you are deleting the same object twice.
When a program has Undefined Behavior, anything could happen, from formatting your hard drive to terminating without any error.
On my platform, for instance, the program enters an infinite loop after returning from main().

BOOST threading : cout behavior

I am new to Boost threading and I am stuck with how output is performed from multiple threads.
I have a simple boost::thread counting down from 9 to 1; the main thread waits and then prints "LiftOff..!!"
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
struct callable {
void operator() ();
};
void callable::operator() () {
int i = 10;
while(--i > 0) {
cout << "#" << i << ", ";
boost::this_thread::yield();
}
cout.flush();
}
int main() {
callable x;
boost::thread myThread(x);
myThread.join();
cout << "LiftOff..!!" << endl;
return 0;
}
The problem is that I have to use an explicit "cout.flush()" statement in my thread to display the output. If I don't use flush(), I only get "LiftOff!!" as the output.
Could someone please advise why I need to use flush() explicitly?
This isn't specifically thread related as cout will buffer usually on a per thread basis and only output when the implementation decides to - so in the thread the output will only appear on a implementation specific basic - by calling flush you are forcing the buffers to be flushed.
This will vary across implementations - usually though it's after a certain amount of characters or when a new line is sent.
I've found that multiple threads writing too the same stream or file is mostly OK - providing that the output is performed as atomically as possible. It's not something that I'd recommend in a production environment though as it is too unpredictable.
This behaviour seems to depend on OS specific implementation of the cout stream. I guess that write operations on cout are buffered to some thread specific memory intermediatly in your case, and the flush() operation forces them being printed on the console. I guess this, since endl includes calling the flush() operation and the endl in your main function doesn't see your changes even after the thread has been joined.
BTW it would be a good idea to synchronize outputs to an ostream shared between threads anyway, otherwise you might see them intermigled. We do so for our logging classes which use a background thread to write the logging messages to the associated ostream.
Given the short length of your messages, there's no reason anything should appear without a flush. (Don't forget that std::endl is the equivalent of << '\n' << std::flush.)
I get the asked behaviour with and without flush (gcc 4.3.2 boost 1.47 Linux RH5)
I assume that your cygwin system chooses to implement several std::cout objects with associated std::streambuf. This I assume is implementation specific.
Since flush or endl only forces its buffer to flush onto its OS controlled output sequence the cout object of your thread remains buffered.
Sharing a reference of an ostream between the threads should solve the problem.

close an unopened stream

I have ifstream and an ofstream that in runtime might be opened or not (depends on what the user enters in command line. i declare the variables anyway, and i have a method that opens the stream if needed.
my problem is at the end of the program i don't know if i need to close them or not.
Is there anyway in c++ to know if a stream was opened? Like in Java you can give a stream the null value and then ask if its null (it means that it was never opened)..
Is it ok to close a stream that was never opened?
this is the code:
int main(int argc, char* argv[]) {
static std::ifstream ifs;
static std::ofstream ofs;
//might or might not open the streams:
OpenStreams(ifs,ofs,argc-1,argv);
........
//here i would like to close the streams at the end of the program
//or not (if they were not opened
return 0;
}
Thanks!
I don't really know, nor care to look. Just leave it to the destructors, the standard file streams will close the files during destruction if needed.
EDIT: On lifetimes of objects and guaranteed destruction...
To follow up the second comment to Ben Voigt that I wrote, this is a small test on object lifetimes:
#include <cstdlib>
#include <iostream>
#include <string>
struct test {
std::string name;
test( std::string const & name ) : name(name) {
std::cout << "test " << name << std::endl;
}
~test() { std::cout << "~test " << name << std::endl; }
};
void foo( bool exit ) {
test t1( "1" );
static test t2( "2" );
test t3( "3" );
if ( exit ) {
std::exit(1);
}
}
int main()
{
foo(false);
std::cout << std::endl;
foo(true);
}
And the result of the execution:
test 1
test 2
test 3
~test 3
~test 1
test 1
test 3
~test 2
It can be seen that during the first execution the construction of the objects in foo occurs in the same order as the code., but when the function exits only the objects with auto storage get destroyed, with the object with static storage outliving the function execution.
In the second call to foo, the auto objects get recreated, while the static object doesn't, as expected, since it was created in a previous call. Because foo calls exit() in the second call, the auto objects in foo don't get destructed. On the other hand, the static object is correctly destructed.
Why not just test this using is_open() before you issue the close()?
No close call needed - the streams close itself when they are open when they are destroyed. Also, the static there looks suspicious. main is called only once, so it doesn't have any effect here (apart from pedantic standardese differences that don't matter here, i think.... Definitely not in the case shown).
That said, you can just call close if a stream is not opened - close will return a null pointer if it wasn't open. (I was looking at the spec for basic_filebuf<>::close - the file streams's close returns void).
File-streams can also handle non-open streams: If the stream wasn't open, it sets the failbit. You can check for that using fail() (which tests whehter the failbit or badbit is set). But there is is_open anyway to test whether the stream is open, but you don't need it for the above reasons.
Just don't make the variables static, that way they automatically close when main() returns.
You can use the is_open method to test if a stream has been opened, then close it.
Why not set a flag before opening a stream. Check the flag again if you need to close the stream object if any.
Better would be to pass that open stream object to the flag while opening a stream & use it to close the stream. If the flag has not been initialized or is null don't close.