Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The consequences and pros/cons of flushing the stream in c++

Tags:

c++

flush

theory

I have recently read an article which stated that using \n is preferable to using std::endl because endl also flushes the stream.
But when I looked for a bit more information on the topic I found a site which stated:

If you are in a situation where you have to avoid buffering, you can use std::endl instead of ‘\n’

Now here comes my question: In which situation is it preferable not to write to the buffer? Because I only saw advantages of that technique. Isn't it also safer to write to the buffer? Because it is smaller than a hard drive it will get overwritten faster than data that is stored on the HD (I am not sure if this is true).

like image 669
TheJavaFan Avatar asked Apr 17 '15 13:04

TheJavaFan


People also ask

What does flushing do in C?

The fflush function in C is used to immediately flush out the contents of an output stream. This is particularly useful in displaying output, as the operating system may initially put the output data in a temporary buffer before writing it to an output stream or file like stdout .

Why do you need to flush the buffer C?

Use the fflush Function to Flush stdout Output Stream in C As a result, there are buffers maintained by the C library for handling the input/output operations when using the stdio function calls. If the user needs to force writing to kernel buffers, it needs to flush the given stream provided by the fflush function.

What is flushing the stream?

Flushing a stream ensures that all data that has been written to that stream is output, including clearing any that may have been buffered. Some streams are buffered to aid performance, e.g. a stream writing to disk may buffer until the content reaches a block size.

What does flushing an output stream do?

flush() method flushes this output stream and forces any buffered output bytes to be written out.


3 Answers

When buffering occurs you will have no guarantees that the data is immediately received before a flush occurs. Under particular circumstances you might experience wrong output ordering and/or loss of information/debug data, e.g.

int main() {         std::cout << "This text is quite nice and might as well be buffered";     raise(SIGSEGV); // Oh dear.. segmentation violation     std::cout << std::endl; } 

Live Example

Output:

bash: line 7: 22235 Segmentation fault      (core dumped) ./a.out 

the above will not print any text since the buffering prevented the right output to be displayed.

Now if you simply add a flushing std::endl at the end of the buffer this is what you get

int main() {         std::cout << "This text is quite nice and might as well be buffered" << std::endl;     raise(SIGSEGV); // Oh dear.. segmentation violation     std::cout << std::endl; } 

Live Example

Output:

This text is quite nice and might as well be buffered bash: line 7: 22444 Segmentation fault      (core dumped) ./a.out 

This time the output is visible before the program termination.

Implications of this fact are manifold. Purely speculative: if the data were related to a server log, your app could have crashed before the actual logging.

like image 152
Marco A. Avatar answered Oct 07 '22 13:10

Marco A.


It will be preferable in any situation in which you want the output to actually appear exactly when it was supposed to appear.

A simple example:

#include <iostream>
int main() {
    std::cout << "Please enter your name: " << std::endl;
    std::string name;
    std::cin >> name;
    ...
}

With buffering, no text will appear on screen before the user is expected to type his/her name, so the user will be confused. (Note that in fact it might be really difficult or impossible to get this example run with buffering fully enabled, as C++ might take special measures to flush std::cout before any input from std::cin, see Why do we need to tie std::cin and std::cout?. But this is just a theoretical example: in case the buffering is fully enabled, the user will not see the prompt.)

Such a situation can occur from time to time, though it might not be very often. Consider writing to a pipe to interact with another process. Or even if your program writes to log file and you personally look into the log file from time to time to see how it runs --- in case of buffering, you usually will not see the output that has been printed from program, but still stays in the buffer yet.

Another important situation to account for --- if your program severely crashes, the buffer contents might not end on the hard drive at all. (I expect the stream destructors to flush the buffer, but a crash can be so severe that no destructors will be called at all.)

like image 35
Petr Avatar answered Oct 07 '22 14:10

Petr


It is preferable to flush the buffer if you need the target of your stream to receive the data before the stream is closed.

A real-life example would be an application log, written from a stream that's always open... You may want to look at this log while the program is still running.

like image 32
Drew Dormann Avatar answered Oct 07 '22 14:10

Drew Dormann