Reputation: 426
From this stack overflow post: Is stdout line buffered, unbuffered or indeterminate by default?
From that post, it states that "The C99 standard does not specify if the three standard streams are unbuffered or line buffered: It is up to the implementation."
#include <stdio.h>
int main(void) {
printf("Enter name: ");
fflush(stdout);
printf("Another name: ");
fflush(stdout);
return 0;
}
So, does that mean every single time we print, and we want to make sure it is visible to the user, that it's the safest bet to just flush it every single time? Since buffering is up to the implementation?
#include <stdio.h>
int main(void) {
puts("Enter name:");
fflush(stdout);
puts("Another name: ");
fflush(stdout);
return 0;
}
Even on a newline, is it still best to just flush every single time?
I want to 100% make sure the user sees the output, therefore is it best to flush every single time? Even on stderr
? Since buffering is up to the implementation?
Upvotes: 2
Views: 4756
Reputation: 154075
I want to 100% make sure the user sees the output, therefore is it best to flush every single time?
For "100% make sure" best practice is not based on flushing after output, but flushing stdout
before input. This is especially true when the output does not end with a '\n'
.
It is best to fflush(stdout);
when
Right before input from stdin
and ...
There has been some output since the prior input from stdin
.
Calling fflush(stdout);
more often than that does not impact functionality, but may unnecessarily slow code.
There is a 2nd case for fflush(stdout);
even without input: Debugging. Sometimes a fatal error occurs with info buffered in stdout
. So a fflush(stdout);
is warranted prior to the suspected bad code for better analysis.
Even on a newline, is it still best to just flush every single time?
For "100% make sure", the rules for flushing stdout
are soft enough to even oblige fflush(stdout);
before reading in this case too.
Yet stdout
should be unbuffered or line buffered on start-up (see next) and usually not require a flush in this case.
Even on stderr?
C spec has "As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device."
As long as the write to stderr
ends with a '\n'
and buffering mode not changed, then the output should be seen.
Interesting to see how C++ handles end-of-line.
What is the difference between endl and \n in C++?
@paxdiablo nicely answers Why does printf not flush after the call unless a newline is in the format string?
Upvotes: 2
Reputation: 490408
Looking at the exact examples you show, it's unlikely there will be a visible difference from calling fflush
. In particular, you just write two lines of data, and then exit. Normal exit from a program (either by calling exit
or returning from main
) requires:
Next, all open streams with unwritten buffered data are flushed, all open streams are closed, and all files created by the tmpfile function are removed.
So, the only possibility here would be if the system crashed (or something on that order) immediately after the first fflush
call, but before your program exited.
I'd guess, however, that the real intent was when you print out the "Enter name: " prompt, you intended for the program to stop and read a name from the user:
printf("Enter name: ");
char name[256];
fgets(name, sizeof(name), stdin);
For cases like this, flushing the output stream is generally unnecessary.
In particular, the standard says:
When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment.
Now, you can make a little bit of an argument that this only talks about what's intended, not what's required. What that basically comes down to is fairly simple: the operating system could do some buffering over which your program has little or no control. So, what it basically comes down to is pretty simple: when you read from stdin
, if anything has been written to stdout
, but not flushed yet, it'll be flushed automatically before the system waits for input from stdin
(unless you've done something like redirecting one or both to a file).
I'm reasonably certain that essentially every argument for doing that flushing explicitly is purely theoretical. In theory, there could be a system that doesn't do it automatically, and that might not quite violate any strict requirement of the standard.
In reality, however, actual systems fall into two categories: those on which the flushing is automatic, so you gain nothing by doing it explicitly, and those on which flushing simply won't do any good, so you gain nothing by doing it explicitly.
Just for an example of the latter, some old terminals for IBM mainframes worked in what you might call a screen-buffered mode. Basically, you'd send a form to the terminal. The user would then edit data into the form. Then when they had filled in the entire form, they pressed a "send" button, and all of the data for the whole form was sent to the CPU at once. On a system like this, calling fflush
won't be (nearly) enough to make code work.
There are systems where calling fflush
is unnecessary.
There are systems where calling fflush
is insufficient.
I'm reasonably certain there is no system where calling fflush
is both necessary and sufficient.
Upvotes: 2
Reputation: 43317
Not really, no. I flush at logical chunks so I can tell more or less where the program crashed and don't have an extra hard debugging time because it crashed with output in the buffer.
The idea is I'm going to call fflush()
just before going and doing something else besides produce more output.
Flush too much = slow code.
Calling fflush()
right before reading input is harmless (the only question is whether it will do it implicitly or not), so if you're doing that for some reason there's no reason to stop doing it.
Upvotes: 0