Is std::cout buffered?
Yes, it's buffered:
C++11 27.4.2 [narrow.stream.objects]/3
: The objectcout
controls output to a stream buffer associated with the objectstdout
The article refers to a 1995 draft version of what became the C++98 standard. I've no idea whether or not that might have said something different.
As for point 2, unitbuf
is initially false on all streams (specified by the post-conditions of the basic_ios
constructor), except for cerr
and wcerr
which explicitly specify otherwise. Again, that may well be different in the ancient draft being referred to.
Usage of output stream buffer in context to std::cout and std::endl
No, your understanding is not correct. "Terminal emulators" are not involved, at least not directly.
The output buffer lives within the stream object itself (std::cout
in this case). There are three possible ways this buffer is used, depending on the buffering policy of the stream:
Block buffered: Output is stored in the buffer first. When the buffer is full, it is "flushed", i.e. its contents are written to the underlying (OS specific) output channel and the buffer is emptied.
Line buffered: Works like block buffered, but the buffer is also flushed whenever a newline (
'\n'
) is written to it.Unbuffered: The output buffer is not used. All output is written immediately.
When you open a file, the stream starts out being block buffered. std::cerr
is unbuffered. std::cout
is line buffered if output goes to a terminal and block buffered otherwise.
std::flush
flushes the output buffer immediately (if there is any).
As for how data is actually written, the details depend on your operating system. On unix systems, there is a system call called write
(a "system call" is a request to the operating system to do something). System calls are typically slower than normal function calls; the output buffer is a performance optimization because you don't want to call write
for every single character of output. Collecting output internally until you have a bigger batch of text to write means fewer calls to write
, which means better overall performance.
As for your specific questions:
No, terminal emulators are not relevant.
The OS.
The buffer is in the stream object, not the terminal emulator. Increasing the buffer size stops giving you any performance benefits after some point. Your program will usually spend most of its time calculating results and doing things other than writing text to
std::cout
.
What does this mean: 'std::cout' is buffered
Here's a related post:
Is std::cout buffered?
And here's an article that talks about it in more detail:
https://www.programmingincpp.com/flush-the-output-stream-buffer.html
How to prevent `std::cin` or `\n` from flushing the buffer of `std::cout`?
You could write to your own std::stringstream
buffer, and then output that to std::cout
when you're ready.
MWE:
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <vector>
using std::cin;
using std::cout;
using std::istream;
using std::runtime_error;
using std::stringstream;
using std::vector;
static auto get_int(istream& in) -> int {
int n;
if (!(in >> n)) {
throw runtime_error("bad input");
}
return n;
}
int main() {
auto ss = stringstream();
auto v = vector<int>();
auto size = get_int(cin);
while(size--) {
auto n1 = get_int(cin);
if (n1 == 0) {
auto n2 = get_int(cin);
v.push_back(n2);
} else if (n1 == 1) {
auto n2 = get_int(cin);
ss << v[n2] << '\n';
} else if (n1 == 2) {
v.pop_back();
}
}
cout << ss.str();
}
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.
How to make a simple C++ program in which std::cout is not flushed
This is not standard c++, but in POSIX, you can send a "kill" signal to kill the running process. This will stop the execution without cleanup such as flushing buffers.
Edit: I realized that signals are not only POSIX but actually part of C standard library (and included in the C++ standard library).
#include <csignal>
// ...
std::cout << "Don't write me to the console!";
std::raise(SIGKILL);
Related Topics
Why Does 'Int ;' Compile Fine in C, But Not in C++
Why Does My Program Hang When Opening a Mkfifo-Ed Pipe
How to Check If Window Is "Always on Top"
Is Infinite Loop Still Undefined Behavior in C++ If It Calls Shared Library
"No Appropriate Default Constructor Available"--Why Is the Default Constructor Even Called
Which One Will Execute Faster, If (Flag==0) or If (0==Flag)
Why Is Auto_Ptr Being Deprecated
Finding "Dead Code" in a Large C++ Legacy Application
Clang Doesn't See Basic Headers
Setjmp/Longjmp: Why Is This Throwing a Segfault
Std::Map Default Value for Build-In Type
Why Do String Literals (Char*) in C++ Have to Be Constants
Initializer List for Dynamic Arrays
What Does "#Define Str(A) #A" Do