C++ Cout and Cin Buffers, and Buffers in General

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.

cout text gets displayed only part of the time

When the buffer reaches a certain length or the program terminates normally, the buffer is flushed.

Use of Buffer in C++

There are multiple reasons that leads to systems taking significant amount of time for I/O operations : the device may be slow (Hard disk drives), it may require to perform various operations before and/or after writing to it, etc.

Then, a buffer reduces the number of interaction with the device by making bigger but less frequent read/write. Then, it reduces the overhead necessary to perform the operation (in the case of a hard drive, you'll want to write big chunk of data infrequently, rather than small chunks frequently, as it costs to find where to write, etc.).

Moreover, with a buffer, you can even control when you want the I/O operation to be done which can be interesting in particular cases (for example, in a real time application, you'll want to avoid I/O operation while you are running the time-constrained part of the code, storing your data in the buffer, and only doing the I/O operations once you've exited the time-constrained part of the code).

How the buffer of cout work?

You are mixing a lot of things. To date:

  • Implementation details of cout
  • Chained calls
  • Calling conventions

Try to read up on them separately. And don't think about all of them in one go.

printf("i=%d i++=%d i--=%d\n" , i , i++ ,i-- );

The above line invokes undefined behavior. Read the FAQ 3.2. Note, what you observe is a side-effect of the function's calling convention and the way parameters are passed in the stack by a particular implementation (i.e. yours). This is not guaranteed to be the same if you were working on other machines.

I think you are confusing the order of function calls with buffering. When you have a cout statement followed by multiple insertions << you are actually invoking multiple function calls, one after the other. So, if you were to write:

cout << 42 << 0;

It really means: You call,

cout = operator<<(cout, 42)

and then use the return in another call to the same operator as:

cout = operator<<(cout, 0)

What you have tested by the above will not tell you anything cout's internal representation. I suggest you take a look at the header files to know more.

Case(s) where output buffer won't flush?

Depends on the system.

Take the following program as an example:

#include <iostream>
#ifdef WIN32
#include <windows.h>
#define sleep(n) Sleep((n)*1000)
#else
#include <unistd.h>
#endif

using namespace std;

int main()
{
cout << "This is line 1";
sleep(4);
cout << endl;
cout << "This is line 2" << endl;

return 0;
}

By inspecting the program, you might surmise that the program would print This is line 1, followed by pausing for 4 seconds, then printing This is line 2.

And if you compile with Visual Studio to run on Windows, you'll get that exact behavior.

On Linux and other Unix operating systems however, the program will appear to be silent for 4 seconds before printing out both lines together. The output won't reliably flush until a new line character is encountered in the output stream.



Related Topics



Leave a reply



Submit