I am jumping from C into C++ with the help of the book C++ Primer (5th edition) where the author states the following:
Programmers often add print statements during debugging. Such statements should always flush the stream. Otherwise, if the program crashes, output may be left in the buffer, leading to incorrect inferences about where the program crashed.
But posts online suggest otherwise; some say constant flushing of the buffer is bad for the program and causes performance issues.
My questions:
std::endl
? P.S.
The only difference is that std::endl flushes the output buffer, and '\n' doesn't. If you don't want the buffer flushed frequently, use '\n' . If you do (for example, if you want to get all the output, and the program is unstable), use std::endl .
To be clear, the vast majority of the time, you should not use endl . See also this answer + comments. remember end-of-line is "\r\n" on a DOS/Windows platform and bare "\r" on some (all?) Mac platform, too.
Both endl and \n serve the same purpose in C++ – they insert a new line. However, the key difference between them is that endl causes a flushing of the output buffer every time it is called, whereas \n does not.
It is a common practice to use std::endl to print newlines while using cout. For small programs with very little I/O operations this practice is acceptable, but if the bulk of I/O operations increase, then the efficiency of the program is compromised.
Debug output should be written to std::cerr
; it's unit buffered, so every character gets flushed. There is rarely a need for std::endl
, and getting in the habit of using it will lead to mysteriously slow code. Just use '\n'
unless you know you need to flush the buffer.
Starting with point 4 because everything else hinges on it and point 3 because it is tightly related.
When you flush the stream, you are taking all data stored by the stream and writing it to the underlying medium represented by the stream.
When it is flushed it is done, committed and ready to be observed by the outside world (More or less. The operating system and the hardware backing the stream may also delay the write, but there isn't much you can do about that). You can't read it until it has been flushed. If it's never flushed, you can't read it.
The thing is you do not want to write to IO very often because anything that goes out of the CPU takes an ungodly amount of time compared to that which stays inside the CPU. Tens of thousands of times slower sometimes. Inside the CPU you have gigahertz and parallel buses moving data 32 or more bits at a time. Outside you have megahertz often moving a single bit at a time.
Take a file as a classic example. Not only is drive access running at a fraction of a speed of the CPU, but if every byte goes directly to a disk, then for every byte you may have to
Brutal. Imagine doing this a few hundred or a few thousand times to write a single string. But what if you only wrote the string when it got too big to hold or you were done? What if you wrote in sectors rather than bytes? Then you could
One operation for potentially thousands of byte in one shot.
Point 2 goes back to point four/three's you can't read what you don't flush. If you want to see a particular output on the screen and you want to see it now, you flush. If you want to get a debug message out before the program crashes, and likely terminates without getting those last few absolutely essential messages onto the screen, you flush. History is full of programmers looking in the wrong place for a bug because they didn't get those last few unflushed error messages.
You are trading program speed for the relative certainty that you will see an important message when you need to see it.
Point 1 calls back to point 2. std::endl
is both an end of line and an instruction to flush the stream. You use it sparingly and only when you need both an end of line and a flush. If you don't need a flush, just send and end of line: '\n'
.
Take Pete Becker's advice and use std::cerr
for errors and debugging where possible. That's what it was built for. It operates on brute force and ignorance. It's painful. It's slow. And it almost always works.
By default std::cout
is linked to stdout
, which is...
fully buffered if and only if the stream can be determined not to refer to an interactive device.
(C99, 7.19.3 Files, paragraph 7.)
This means, if your output is sent to terminal, std::endl
vs. "\n"
makes no difference in the first place. ;-)
Regarding your actual question:
Both is true:
This only becomes a problem once you add "always".
When should you use
std::endl
?
When you want to flush the buffer.
Is the author wrong or did I miss understand any part of what he stated?
I think absolute quantifiers like "always", "all", "never" etc. should be taken with a grain of salt as far as style / design / etc. is concerned.
(Exception: Never invoke undefined behaviour. ;-) )
Can you give any real world scenarios for actual need of flushing the output stream?
Whenever not having the latest output actually appear would not be acceptable. Whether this is the case in any given scenario is a judgement call.
Personally, I would consider production / transaction logs to be more critical than debug logs...
Both the author and the posts are right.
stream << std::endl
is actually stream << '\n' << std::flush
. Explicit flushing has performance drawbacks, and this is why you shouldn't use it in performance-critical situations. You rarely think about such negligible performance issues while debugging, so it actualy is a good practice to explicitly flush debug output.
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