1

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?

Jack Murrow
  • 396
  • 3
  • 11
  • 1
    You can't be 100% sure (and the standard does not attempt to guarantee) that (1) there is a user; (2) there is an output device; (3) the output device, if it exists, is visible to the user, if they exist. But ***if*** there is a user and an interactive device visible by them, and if that interactive device is attached to the three standard streams, then the intent of the standard is that output written to `stderr` is immediately visible and output written to `stdout` is visible before any subsequent input request. Flushing should not ge necessary. – rici Dec 20 '20 at 22:54
  • @rici I too would hope "the intent of the standard is ... output written to stdout is visible before any subsequent input request.", yet I do not find C spec support for that claim. Are you aware of any? – chux - Reinstate Monica Dec 20 '20 at 22:59
  • @chux: clear statement of intent in section 5.1.2.3/6: "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.**" (Emph added) – rici Dec 20 '20 at 23:13

3 Answers3

2

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.

Summary

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.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • I've seen one too many progress bars that didn't work when not connected to the terminal because the progress bar ended up getting buffered. It's really annoying when writing GUI wrappers for console programs. – Joshua Dec 20 '20 at 22:13
  • A progress bar is a rather different situation: we're doing output but *not* reading input. Yes, for a case like that, flushing can be helpful. – Jerry Coffin Dec 20 '20 at 22:31
1

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

  1. Right before input from stdin and ...

  2. 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?

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Where did you find a system that doesn't link stdin to stdout in this modern era? – Joshua Dec 20 '20 at 21:57
  • 1
    @Joshua My ellipse environment appears to be fully buffered. In any case, a `fflush(stdout);` before any interactive user input certainly does not slow the process given the huge time waiting for user input. Should you seek deeper more better documented cases, consider posting that question. – chux - Reinstate Monica Dec 20 '20 at 22:00
  • @chux-ReinstateMonica Does "unbuffered" mean every print in the output is flushed, or does "unbuffered" mean it's never flushed? – Jack Murrow Dec 20 '20 at 22:04
  • 1
    @JackMurrow: "Does "unbuffered" mean every print in the output is flushed" -- Effectively yes, even though the word "flushed" does not make sense in this context, because with unbuffered output, there is no buffer that could be flushed, because the buffer doesn't even exist. – Andreas Wenzel Dec 20 '20 at 22:07
  • So is it possible that a stream can have a buffer but be never automatically flushed at all? Like for example, "line buffered" has a buffer and flushes every new line, but are there buffers that are never flushed automatically like "line buffered"? – Jack Murrow Dec 20 '20 at 22:14
  • @JackMurrow Yes, yet typicality fully buffer streams flush when the internal buffer is full, say 4K. Even line buffering will typically flush when a sub-portion of a line exceeds a certain size, again say 4K. The implementation defined details allow a wide range of behaviors. For code I write, I generally use `fflush(stdout)` when 1) the prior output might not be line terminated before a `stdin` function or 2) for highly portable code. It comes down to do you code per spec or code per experience - I go for an in-between style. – chux - Reinstate Monica Dec 20 '20 at 22:30
  • Is it possible that a stream can be neither line-buffered or unbuffered, or **must the stream be line-buffered or unbuffered**? – Jack Murrow Dec 21 '20 at 04:06
  • @JackMurrow Streams are generally classified 1 of 3: fully buffered, line buffered, unbuffered. `setvbuf()` may be used to attempt to change a streams default buffering with `_IOFBF, _IOLBF, _IONBF`. The precise details of how buffering works is allotted latitude "Support for these characteristics is implementation-defined". – chux - Reinstate Monica Dec 21 '20 at 05:18
  • If the stream is fully buffered, does it mean it will never flush by itself / automatically? The only time it flushes is if you flush it, basically? – Jack Murrow Dec 21 '20 at 06:36
  • 1
    @jack, no, as stated above, the buffer is flushed when it gets full. Also when the file is closed, explicitly or implicitly (for example, when the program terminates). Or when you call seek. Or when input is requested from the same file. Or any other time the library finds convenient. – rici Dec 21 '20 at 06:54
0

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.

Joshua
  • 40,822
  • 8
  • 72
  • 132