std::endl, Buffers, and Flushing
Both '\n' and std::endl write a newline, but std::endl also flushes the stream. Recommendation: Prefer '\n' when you don't need the flush.
std::cout << "Hello" << std::endl; // Newline + flush
std::cout << "Hello" << '\n'; // Just a newline (usually sufficient)That said, in most programs this difference is negligible and it's not something to worry about.
I/O Buffering
I/O in C++ is buffered. Characters you write to a stream aren't instantly sent to the terminal or disk. Instead, they're collected in an internal buffer and written later. This batching makes I/O more efficient by reducing system call overhead.
Flushing forces all buffered characters to be written immediately. You can flush manually with << std::flush or .flush(). Flushing also happens automatically when your program exits (but not through abort or _exit).
Buffering Modes
Streams can operate in different buffering modes, which affect when automatic flushing occurs:
- Fully buffered: Flushes only when the buffer is full. Typical for file output.
- Line buffered: Flushes when a newline is written (or when the buffer is full). Typical for terminal output.
- Unbuffered: No buffering; each write goes directly to the destination.
std::cerruses this by default.
Because terminal output is typically line-buffered, '\n' triggers a flush automatically, so std::endl and '\n' often behave the same for console output.
File output is typically fully buffered, so '\n' won't flush. This is where the distinction matters most:
// Flushes after every line (slower for lots of output)
for (int i = 0; i < 10000; ++i) {
file << i << std::endl;
}
// Buffer flushes only when full (more efficient)
for (int i = 0; i < 10000; ++i) {
file << i << '\n';
}For occasional output, the difference won't matter. In tight loops writing to files, it can be noticeable.
When to Flush
Explicit flushing is useful when you need output to appear immediately:
- Progress indicators: Partial lines that should display before the next operation
- Debugging output: Ensuring messages appear before a potential crash
- Logging: When log messages must be written immediately
std::cout << "Processing... ";
std::cout.flush(); // Show "Processing... " before the work starts
do_lengthy_work();
std::cout << "done.\n";For interactive prompts, reading from std::cin automatically flushes std::cout, so explicit flushing is often unnecessary.
For debugging, consider std::cerr instead, which is unbuffered by default.
See Also
- std::cout
- std::endl
- std::flush
- std::cerr
- "std::endl" vs "\n" on Stack Overflow
