23

Is it recommended that C++ programmers frequently write lines like

std::cout << "output: " << i << " and " << j << std::flush;
//more
std::cout << "ending newline." << std::endl; //endl does flush

In other words, in output lines that don't have endl, should we be flushing alot, just in case? Or is this not really needed anymore these days on most platforms?

roger.james
  • 1,478
  • 1
  • 11
  • 23
  • 5
    std::endl behavior calls flush automatically. The only reason to use `\n` is if you don't want to flush – SheetJS Jun 28 '13 at 17:10
  • 23
    Only when they frequent the bathroom. – David G Jun 28 '13 at 17:10
  • 1
    The biggest use-case I've found for flushing is for file I/O. Often when I absolutely need a file written out before I continue. (to protect against data loss during unexpected crashes or power outages.) – Mysticial Jun 28 '13 at 17:15
  • 1
    @Mysticial: `std::flush` and `std::endl` do _NOT_ prevent data loss during unexpected power outages, merely unexpected crashes. They flush to the OS, _but not to disk_. – Mooing Duck Jun 28 '13 at 17:41
  • @MooingDuck I thought that was only true when you explicitly disable write flushes via Device Manager. (which even warns you about doing so) A lot of programs rely on `flush()` to flush all the way to disk. – Mysticial Jun 28 '13 at 17:43
  • 5
    @Nirk *"The only reason to use `\n` is if you don't want to flush"* - You meant the only reason not to use `\n` is if you want to flush. – Christian Rau Jun 28 '13 at 17:44
  • Does std::endl flush when the stream is a file? I thought it was only in the console. – ChronoTrigger Jun 28 '13 at 17:45
  • @0x499602D2: And wash your hands. – Keith Thompson Jun 28 '13 at 17:46
  • @MooingDuck Ok. The [Windows `FlushFileBuffers()` function explicitly](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364439(v=vs.85).aspx) states that it goes all the way to the device. That's the one that I use. Maybe the C++ flush doesn't have that guarantee or is IB. – Mysticial Jun 28 '13 at 17:47
  • @Mysticial: officially it's IB, and I'd _heard_ that it doesn't go to disk, but I don't recall which OS I was hearing about nor did I confirm it. – Mooing Duck Jun 28 '13 at 18:00
  • @Mysticial: MSVC's `std::flush` calls `fflush`. [`fflush`](http://msdn.microsoft.com/en-us/library/9yky46tz(v=vs.90).aspx) says "The commit-to-disk feature of the run-time library lets you ensure that critical data is written directly to disk rather than to the operating-system buffers." [Commit to Disk](http://msdn.microsoft.com/en-us/library/aa272064(v=vs.60).aspx) says "By default, calls to the fflush or _flushall library functions write data to buffers maintained by the operating system. The operating system determines the optimal time to actually write the data to disk." – Mooing Duck Jun 28 '13 at 18:19
  • @MooingDuck Ah thx! Though I had to read that some 3 times to get what it said. – Mysticial Jun 28 '13 at 18:24
  • `Without rewriting an existing program, you can enable this feature by linking the program's object files with COMMODE.OBJ` Yuck – Lightness Races in Orbit Apr 20 '14 at 11:47

2 Answers2

20

Your average program does not require frequent flushing. Flushing is something nearer to a special case needed in a few situations:

  • Interacting with a human or other system: flushing output before waiting for input is sensible.
  • Going dormant for awhile: Flushing before extended sleep or waiting simplifies examination of logfiles, makes databases consistent most of the time, etc.

If buffering is not needed, it would be better to disable buffering in the first place instead of throwing in a lot of flushes.

Most of the time, programs benefit by having buffering enabled. Sometimes they generate a few characters here and there. Other times they output a blast of lines.

In all my decades of engineering, my most dramatic performance increases are often realized simply by improving buffering. Sometimes by increasing the default FILE buffer size above 512 bytes (the default) to 4K or 32K (sometimes higher). Other times by adding a layer of buffering or caching. Usually there is high overhead with each trip through the operating system's i/o system. Reducing the total number of system calls is (usually) an easy and highly effective scheme to improve performance.

wallyk
  • 56,922
  • 16
  • 83
  • 148
  • 1
    I don't think you need to flush output before waiting for input. They're tied by default. – Mooing Duck Jun 28 '13 at 17:46
  • @MooingDuck Exactly. With regards to the C++ standard streams there is no need to flush before requesting input: http://en.cppreference.com/w/cpp/io/basic_ios/tie (See especially the Notes section). – Oberon Jun 28 '13 at 17:50
  • @MooingDuck: I believe that is true only with `cin` and `cout` which are specially tied together. But other `ostream` would have to be explicitly synced one way or the other. – wallyk Jun 28 '13 at 17:55
  • 2
    @wallyk "By default, the standard streams cin, cerr and clog are tied to cout. Similarly, their wide counterparts wcin, wcerr and wclog are tied to wcout." But for other ostreams you would of course have to manually tie() them (instead of manually flushing). – Oberon Jun 28 '13 at 17:57
15

Flushing is generally not the greatest habit to get into, as flushing can slow down your program at times if you're constantly writing out to IO. You can control how you flush by either explicitly using std::endl or std::flush (with std::endl just inserting a \n into a stream and then calling flush).

@StackedCrooked in the C++ Lounge put together an experiment about the cost of flushing versus not flushing at all: http://coliru.stacked-crooked.com/view?id=55c830cf9a144559f31963de41fa9405-f674c1a6d04c632b71a62362c0ccfc51

Not-flushing does relatively well after repeated use, while flushing adds a bit of overhead everytime you invoke it: you are honestly better off not manually std::flush-ing your streams. Just do it once at the end of the program or after the end of a critical section of code.

It's also good to note that you should probably flush just before you do anything with the user, so the program isn't not-writing things to the output that a user should be seeing in a Log File or other place.

EDIT: Relevant analogy: In simple terms, what is the purpose of flush() in ostream

Community
  • 1
  • 1