I see so many people confused about the use of “std::endl” versus “\n”, so here I explain when they should be used…
The use of std::endl will insert an end of line character.
It will also flush the pipe in which it is used on! This is important to know and I will explain why below.
The use of “\n” will insert an end of line character.
When should I use each?
It depends on your use case, but generally you should use “\n”, unless you need to flush the buffer for some reason.
When should I flush the buffer?
When you write to a standardized stream the output is buffered and then after some X number of chars or other special events (e.g. std::endl, std::flush) the buffer is flushed and all data is written to the stream.
Using this built-in buffer helps speed up your program as writing to these streams can be very slow, especially if you are going to disk. However, if you can minimize how often you write to the stream and instead write in large bursts less often then the overall program will run faster (hence the purpose of buffering streams).
However, if the program exits and unflushed buffers exist, then they are not guaranteed to be flushed before termination.
You have probably seen this behavior when some messages weren’t appearing even though you knew you had hit a line of code that wrote to that stream. This is also why some streams (e.g. std::cerr) are completely unbuffered.
If you write an error message to a buffered pipe and then throw an exception, it is unlikely that the error message will be printed before the program exits. This is why error messaging pipes are configured (by default) to be unbuffered.
For streaming to disk
If you are calling std::endl for every line you stream to disk, then you are making your program unnecessarily slow and hammering the disk IO (maybe even network IO) which is very inefficient.
While you certainly shouldn’t flush every line you write to disk, it is important to flush the buffer to disk once you are done writing to it.
For writing to a display
Like I mentioned early std::cerr (STDERR) is unbuffered, but std::cout (STDOUT) is buffered.
If you want to call std::endl when writing to std::cout to guarantee that those lines are printed in case the program exits then you can do that, but make sure you have good justification for writing to std::cout. Seeing as std::cerr is unbuffered, you should ask yourself if std::cerr is a better fit for your use-case?
You can use flush lines you write to std::cout (STDOUT), but it is inefficient. The std::cerr (STDERR) stream is unbuffered and was designed for this purpose, so consider using it instead.