I have recently read an article which stated that using \\n
is preferable to using std::endl
because endl
also flushes the stream.
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 been crashed before the actual logging.
I hope you've lost the link to that site that you found. std::endl
does not avoid buffering. It flushes whatever is in the buffer. If you need to avoid buffering, use setf(ios_base::unitbuf)
. That sets the stream to flush after each insertion. That's the default setting for std::clog
. The reason for doing this is that the less stuff being held in the buffer, the greater the chance that critical data will have been written to the stream when the program crashes.
Flushing also matters for interactive programs: if you write a prompt to std::cout
, it's a Good Thing if that prompt shows up on the display before the program starts waiting for input. That's done automatically when you use std::cout
and std::cin
, unless you've messed with the synchronization settings.
Many programmers seem to use std::endl
as a fancy way of spelling '\n'
, but it's not. You don't need to flush the output buffer every time you write something to it. Let the OS and the standard library do their jobs; they'll take care of getting the output to the appropriate place in a timely manner. A simple std::cout << '\n';
is all that's needed to put a newline into the output, and sooner or later, that will show up on the display. If you need to have it show now, typically because you've written all of the output for the time being and don't want to leave the displayed information incomplete, use std::endl
after the last line of the output.
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.
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.)
First, a bit of revisionist history.
In the old days, when everybody used stdio.h
library to do I/O, text that was viewed interactively was typically line buffered (or even unbuffered), and text that was not was fully buffered. So, if you output '\n'
to the stream, it would "always" do the Right Thing: lines users were looking at get flushed and seen immediately, and lines getting dumped to file get buffered for maximum performance.
Unfortunately, it isn't actually always the Right Thing; the runtime cannot always predict how users actually want to view the output of your program. One common trap is redirecting STDOUT
-- people get used to running their program in a console and seeing the output (with its line-buffered behavior) in the console, and then for whatever reason (e.g. long running job) they decide to redirect STDOUT
to a file, and are promptly surprised by the fact the output is no longer line-buffered.
I have seen weeks of supercomputer time wasted for this reason; the output was infrequent enough that the buffering prevented anyone from being able to tell how the job was progressing.
C++'s iostream
library, however, was designed to make it easy to do the Right Thing here. Except when synchronizing with stdio
, it doesn't do this funny "maybe line-buffered maybe fully-buffered" thing. It always uses full buffering (except when you do unbuffered stuff, of course), and if you want things flushed on newline, you do so explicitly.
So if you're dumping a bunch of formatted text to a file that people won't be looking at until it's done, you write \n
for your line breaks.
But if you're writing text people might actually want to look at while you're writing it, you use std::endl
for your line breaks, and it gets displayed immediately. And if you're writing several lines at once, you can even do better: use '\n'
for the intermediate line breaks and std::endl
for the final one (or '\n'
and std::flush
). Although in this setting performance usually doesn't matter so it's usually fine to just use std::endl
for all of the line breaks.