3

I know there are many buffer questions on here but I can't seem find a clear answer on this.

std::cout << "write to screen" << std::endl;

I know this code will write to the screen and flush the buffer because of the "endl", but if I wrote this:

std::cout << "write to screen";

Wouldn't the buffer be flushed regardless since the text has been outputted to the screen?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Memnite
  • 33
  • 1
  • 3
  • 1
    If your second line was equivalent, aside from omitting the explicit flush, the answer might be yes. Put another way, omitting the `\n` can significantly change things. – Deduplicator Jan 12 '15 at 21:19

4 Answers4

4

Wouldn't the buffer be flushed regardless since the text has been outputted to the screen?

Assuming that you have seen the text outputted to the screen, then yes, the buffer has been flushed.

I believe the confusion is regarding this line:

std::cout << "write to screen";

The absence of std::endl doesn't mean "don't flush the buffer". It simply means "I'm not saying when to flush the buffer".

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • I'm starting to get the impression that "flushing the buffer" is generally not something that needs to be considered when writing code. It flushes on a successful output and automatically flushes when it reaches a certain "watermark". – Memnite Jan 12 '15 at 21:12
  • @Memnite it **very often** does not need to be considered. – Drew Dormann Jan 12 '15 at 21:16
  • @Memnite _"It flushes on a successful output and automatically flushes when it reaches a certain 'watermark'"_ So that's exactly what I've been answering in detail? – πάντα ῥεῖ Jan 12 '15 at 21:28
  • 1
    @πάνταῥεῖ yours was a fine answer. I think there was some guesswork needed regarding what the *real question* was. – Drew Dormann Jan 12 '15 at 21:35
3

There are multiple ways to ensure your std::ostream is flushed:

  1. Manually with std::endl, std::flush, or a direct call to ostream::flush().
  2. Depending on a later used input stream being bound to your ostream: std::basic_ios::tie().
  3. Depending on the tie to C streams: std::ios_base::sync_with_stdio

    This means that anything which would flush the corresponding C stream will also flush the C++ stream, like a call to fflush(), or the (maybe automatically) selected buffering strategy.
    Like line-buffering.

    From C11 draft:

    7.21.3 Files

    3 When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions.
    7 At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.

  4. Waiting on the internal buffer overflowing.

Now, as a general guideline: Don't manually flush your streams, doing so can significantly degrade performance. Unless, of course, it's neccessary for correctness.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
2
std::cout << "Hello" << std::endl;

will write to the screen before executing the next line of code, while

std::cout << "Hello\n";

will print the same, but some time before your program exits normally or you use std::cin (or another instream you tie to std::cout by hand). That means that if your program is terminated abruptly or hangs in an infinite loop, you might not see the output at all.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • 1
    Not quite right - the buffer is flushed as soon it is full (stdio buffers might be tiny) –  Jan 12 '15 at 20:49
  • 1
    @DieterLücking I think this is covered by "some time before". Even if it does not buffer at all, my statement should still be true. – Baum mit Augen Jan 12 '15 at 20:50
  • Actually, it will have the same flushing semantics as `stdout`, or flush even more often. – Deduplicator Jan 12 '15 at 21:00
  • @Deduplicator I never said it will not flush early, just that it might or might not. The only thing we know is that it will flush before one of the above mentioned happen (I did not write *"immediately before"*). I am sorry, I still do not understand why what I wrote is wrong. It would be nice if you could elaborate or just correct my answer if you prefer. Thank you for your time! – Baum mit Augen Jan 12 '15 at 21:09
1

"Wouldn't the buffer be flushed regardless since the text has been outputted to the screen?"

No! std::endl implies flushing. The underlying buffer won't be flushing (written on the screen), until hitting a certain watermark (buffer size).

If you want to have it flushed, call cout.flush() explicitely:

std::cout << "write to screen";
std::cout.flush();

The real key to the solution is, what the underlying std::basic_streambuf interface actually implements.
There could be various implementations:

  1. Calling flush() every time the certain watermark of the underlying buffer is hit
  2. Calling flush() every time (not very efficient)
  3. Calling flush() as soon a '\n' had been printed
  4. Calling flush() as guaranteed with std::endl

The internal buffer management shouldn't be your business of concern, unless you're trying to provide your own std::basic_streambuf implementation.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • So, outputting to the screen does not free the memory used to store the text "write to screen"? – Memnite Jan 12 '15 at 20:51
  • 1
    @Memnite _"does not free the memory used to store the text "write to screen"?"_ There's no relation about _freed memory_ or memory management at all. Don't wrap your head around that. – πάντα ῥεῖ Jan 12 '15 at 20:52
  • Ok, thanks for the help. I'm just trying to understand this concept thoroughly before moving on to learn something new. – Memnite Jan 12 '15 at 21:01
  • Thank you very much for the help, I think I have a better grasp of this now. – Memnite Jan 12 '15 at 21:19