9

According to to this post std::cout will automatically flush on \n when it is attached to an interactive device (e.g. a terminal window). Otherwise (e.g. when being piped to a file) it will act fully buffered and will only flush on .flush() or std::endl.

Is there a way to override this behaviour in Microsoft Visual C++ so that I can select whether I want fully buffered or line buffered mode?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
pauldoo
  • 18,087
  • 20
  • 94
  • 116
  • Maybe this can be useful, I doubt it helps you much with your problem though. http://nibuthomas.com/2009/02/12/writing-endl-like-functions-for-output-streams/ – Skurmedel Apr 28 '09 at 09:16
  • It seems there is some debate as to the legitimacy of the claim that C++ incorporates the C90 line-buffered vs fully-buffered distinction for std::cout. Regardless, is there a way to change between buffering modes with MSVC? – pauldoo Apr 28 '09 at 16:05
  • Maybe you could write a test program and see if the claim is true? – Skurmedel Apr 29 '09 at 11:03

3 Answers3

14

Contrary to anon's (Apr 28 '09) answer, this behavior has nothing to do with the operating system or "console software."

C++'s <iostream> streams are designed to be interoperable with C's <stdio.h> streams. The goal is to allow uses of std::cout to be intermixed with uses of printf/puts. To achieve this, std::cout's streambuf is implemented atop C's stdout stream. It is actually C's stdout that is line-buffered when the standard output is attached to a terminal device.

You can call std::ios_base::sync_with_stdio(false) (before your program uses any of C++'s standard I/O streams) to tell the C++ streams library to communicate directly with the underlying file descriptors rather than layering atop C's streams library. This avoids C's stdout stream entirely and speeds up C++'s I/O streams at the cost of the two libraries no longer mixing well.

An alternative is to unconditionally set stdout to fully buffered by calling std::setvbuf(stdout, nullptr, _IOFBF, BUFSIZ). Then, even though std::cout is still writing through stdout, you will not have stdout flushing after every newline.

Matt Whitlock
  • 756
  • 7
  • 10
1

This is not an issue with C++ (there is no language requirement that \n flushes anything) but with your operating system and/or console software. If the console wants to flush its buffer when it sees a newline, then it can, and I would guess that most do so. Note that it is important to differentiate between the C++ runtime's buffers (which can be to some extent controlled from your C++ code) and the buffers of the console application (over which it has no control).

FYI, there is a flag in the standard iostream library called unitbuf which if set causes the buffers to be flushed after each output operation. It is set, for example, for the std::cerr stream. This has nothing to do with the '\n' character however, as you can output multiple '\n' s in a single operation.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • From the page I linked to: "If standard output is or may be attached to an interactive device, it is line-buffered; otherwise it is fully buffered. (C99 specifies this in section 7.19.3 paragraph 7; I believe C90 says the same, and C++98 incorporates C90 by reference.)" Do you believe this to be wrong? – pauldoo Apr 28 '09 at 10:49
  • 2
    I don't have access to the C Standard documents, so can't really comment. However, the C++ Standard does NOT incorporate the C Standard, by reference or otherwise. The C++ Standard refers to the C standard in specific cases. –  Apr 28 '09 at 11:07
  • @pauldoo: I've heard that claim about C++ incorporating C before, but as far as I know, it only refers to specific sections. Do you have a source for this? – jalf Apr 28 '09 at 11:27
  • I'm afraid the only reference I have is the forum post I linked to in my original question. – pauldoo Apr 28 '09 at 16:03
0

An implementation is free to flush whenever it feels it is appropriate. It varies from vendor to vendor whether they flush on \n or not.

I can see something called ios_base& nounitbuf(ios_base& str); from my C++0x draft. Give it a shot. This is about the only thing that standard C++ gives you.

dirkgently
  • 108,024
  • 16
  • 131
  • 187
  • Hm, I wasn't sure so I had mentioned the draft. – dirkgently Apr 28 '09 at 10:38
  • However, diligent research indicates there is a stream flag "unitbuf" setting this should flush the stream after each operation. I'll update my answer to reflect this. –  Apr 28 '09 at 11:21