I have recently read a lot about standard output buffering. I'm aware that printf
is buffered but so far I thought that its buffer only gets flushed when a new line is read into the buffer or fflush(stdout)
is called or the process that called printf
exited normally.
I wrote this program which calls printf without a new line just before scanf
. When I googled that, I found a lot of people saying they didn't understand why scanf was executed before printf. Since I now understand the concept of stdout buffering, that makes sense to me.
However, in my case, the buffer is flushed just before I run scanf. It does make sense to do so because the user probably wants the printf to be executed before any scanf, but how is it happening? What exactly is flushing stdout? Is it scanf?
int main(void) {
char things;
printf("Hello ");
scanf("%c", &things);
}
(I am running Arch Linux)
Edit: Due to some comments saying my system's stdout is unbuffered, I just want to add that without running scanf
on my program, my program has exactly the behaviour I mentioned above, it is definitely buffered.
This is a quality of implementation issue.
The C Standard only mandates that stdin
and stdout
be fully buffered by default only when attached to a regular file. But it explicitly encourages specific behavior for interactive devices:
5.1.2.3 Program execution
[...]
The least requirements on a conforming implementation are:
[...]
The input and output dynamics of interactive devices shall take place as specified in 7.21.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input.
On many Posix systems, stdin
and stdout
are line buffered when attached to a character device and stdout
is then flushed automatically when a read attempt from stdin
requires reading from the underlying system handle. This allows the prompt to appear on the terminal even without a trailing newline.
On linux, this behavior is specified in the stdio(3) linux manual page:
Output streams that refer to terminal devices are always line buffered by default; pending output to such streams is written automatically whenever an input stream that refers to a terminal device is read. In cases where a large amount of computation is done after printing part of a line on an output terminal, it is necessary to fflush(3) the standard output before going off and computing so that the output will appear.
Yet the GNU libc has a subtly different behavior: only stdout
is flushed this way as coded in glibc/libio/fileops.c (as modified by Ulrich Drepper on 2001-08-04 23:59:30):
/* Flush all line buffered files before reading. */
/* FIXME This can/should be moved to genops ?? */
if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
{
#if 0
INTUSE(_IO_flush_all_linebuffered) ();
#else
/* We used to flush all line-buffered stream. This really isn't
required by any standard. My recollection is that
traditional Unix systems did this for stdout. stderr better
not be line buffered. So we do just that here
explicitly. --drepper */
_IO_acquire_lock (_IO_stdout);
if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF))
== (_IO_LINKED | _IO_LINE_BUF))
_IO_OVERFLOW (_IO_stdout, EOF);
_IO_release_lock (_IO_stdout);
#endif
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With