Does New Line Character Also Flush the Buffer

Does new line character also flush the buffer?

Converting comments into an answer.

It depends on where cout is going. If it goes to a terminal ('interactive device'), then it can't be fully buffered — it is usually line buffered, meaning that characters appear after a newline is printed, or could in theory be unbuffered. If it is going to a pipe or file or other non-interactive destination, the endl forces the data out even if the stream is fully buffered, as it usually will be.

I also wanted to know if I provided neither new line character nor endl, will the output be displayed on the stdout once it reaches the end of the program, I know it does for terminal, but is it applicable to all types of stdout?

Yes, when the file stream is closed at the (normal) end of the program, pending output will be flushed. It'll also be flushed when the buffer is full. If the program aborts, pending output usually won't be flushed.

Does printf always flush the buffer on encountering a newline?

No, the standard says that stdout is initially fully buffered if the output device can be determined to be a non-interactive one.

It means that, if you redirect stdout to a file, it won't flush on newline. If you want to try and force it to line-buffered, use setbuf or setvbuf.

The relevant part of C99, 7.19.3 Files, paragraph 7, states:

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.

Just keep in mind section 5.1.2.3/6:

What constitutes an interactive device is implementation-defined.

how endl mainly affects fully buffered streams?

There are three main buffering strategies used for output streams:

  1. No buffering - Every write to the stream is immediately written to the underlying output device.
  2. Line buffering - Writes to the stream are stored in memory until a newline character is written or the buffer is full, at which point the buffer is flushed to the underlying output device.
  3. Full buffering - Writes to the stream are stored in memory until the stream's internal buffer is full, at which point the buffer is flushed to the underlying output device.


why endl mainly affects the fully buffered streams

This should be fairly apparent from the descriptions above. If the stream is unbuffered then std::endl doesn't do any extra work; there is no buffer to flush. If the stream is line buffered, then writing a newline will flush the buffer anyway, so std::endl doesn't do anything extra. Only for a fully buffered stream does std::endl do any extra work.



how cout is not a fully buffered stream?

The C++ language doesn't specify the buffering strategy used for std::cout, but most implementations use either no buffering or line buffering when the program's standard output stream is hooked up to a terminal. If stdout is redirected to something else, like a file, many implementations will switch to using a fully buffered stream for std::cout.

endl and flushing the buffer

Output is generally buffered before it's written to the intended device. That way, when writing to slow to access devices(like files), it doesn't have to access the device after every single character.

Flushing means emptying the buffer and actually writing it to the device.

Why does printf not flush after the call unless a newline is in the format string?

The stdout stream is line buffered by default, so will only display what's in the buffer after it reaches a newline (or when it's told to). You have a few options to print immediately:

  • Print to stderrinstead using fprintf (stderr is unbuffered by default):

    fprintf(stderr, "I will be printed immediately");
  • Flush stdout whenever you need it to using fflush:

    printf("Buffered, will be flushed");
    fflush(stdout); // Will now print everything in the stdout buffer
  • Disable buffering on stdout by using setbuf:

    setbuf(stdout, NULL);
  • Or use the more flexible setvbuf:

    setvbuf(stdout, NULL, _IONBF, 0); 

Why is it important to flush characters stored in buffer?

Normally, terminals are line buffered, so if the output from print doesn't contain a newline you won't see anything until a newline is emitted, or when the program ends and stdout is flushed as part of the closing process. In that situation you need to add the flush=True arg to the print call. You could also call sys.stdout.flush() explicitly, but it's more convenient (and slightly faster) to let print handle it. In Python 2, you have no option but to call sys.stdout.flush().

However, in Python 3, the print function kindly performs a buffer flush for you if there's a \r (carriage return) in the output. So in that situation, you don't need to worry about flushing.

OTOH, be aware that some IDEs / terminals may not support this behaviour, and you will need to use either flush=True or sys.stdout.flush() with them. For that matter, some IDEs may not even behave correctly when printing with \r and end='' even if you do explicitly flush, for example Spyder.

What are the rules of automatic stdout buffer flushing in C?

Rules of automatic flushing stdout buffer is implementation-defined (ID). It is ID when the stream is unbuffered, fully buffered, or line buffered.

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, ... C11dr §7.21.3 3



I'm just curious which conditions should be satisfied to flush stdout buffer automatically.

If code wants to insure output is certainly flushed, use fflush(). Other conditions that may automatically flush the stream are implementation defined.

What does it mean to flush the input buffer?

"Flushing the input buffer" refers to the attempt to discard unwanted characters from the input stream so that they do not perturb later input calls.

In your code, it doesn't look like you'll have this problem, so flushing the input buffer should not be an issue for you.

The unwanted input issue typically occurs when you're doing input using scanf. scanf typically leaves the user's newline on the input buffer, but later calls to getchar or fgets (or even scanf) can be badly confused by this.

The problem with flushing the input is that there isn't really a good way of doing it. A popular although not recommended technique is to call fflush(stdin). That looks like it ought to be just the ticket, but the problem is that it's not well-defined and not guaranteed to work (although some programmers have found that it works well enough for them, on some platforms).

See this question and this question (maybe also this one) for much more on this issue.

Most efficient way to output a newline

The answer to this question is really "it depends".

In isolation - if all you're measuring is the performance of writing a '\n' character to the standard output device, not tweaking the device, not changing what buffering occurs - then it will be hard to beat options like

 putchar('\n');
fputchar('\n', stdout);

std::cout.put('\n');

The problem is that this doesn't achieve much - all it does (assuming the output is to a screen or visible application window) is move the cursor down the screen, and move previous output up. Not exactly a entertaining or otherwise valuable experience for a user of your program. So you won't do this in isolation.

But what comes into play to affect performance (however you measure that) if we don't output newlines in isolation? Let's see;

  • Output of stdout (or std::cout) is buffered by default. For the output to be visible, options include turning off buffering or for the code to periodically flush the buffer. It is also possible to use stderr (or std::cerr) since that is not buffered by default - assuming stderr is also directed to the console, and output to it has the same performance characteristics as stdout.
  • stdout and std::cout are formally synchronised by default (e.g. look up std::ios_base::sync_with_stdio) to allow mixing of output to stdout and std::cout (same goes for stderr and std::cerr)
  • If your code outputs more than a set of newline characters, there is the processing (accessing or reading data that the output is based on, by whatever means) to produce those other outputs, the handling of those by output functions, etc.
  • There are different measures of performance, and therefore different means of improving efficiency based on each one. For example, there might be CPU cycles, total time for output to appear on the console, memory usage, etc etc
  • The console might be a physical screen, it might be a window created by the application (e.g. hosted in X, windows). Performance will be affected by choice of hardware, implementation of windowing/GUI subsystems, the operating system, etc etc.

The above is just a selection, but there are numerous factors that determine what might be considered more or less performance.



Related Topics



Leave a reply



Submit