In a normal C program running on a modern OS, file access is buffered twice (or more when you count buffers like the buffer in your drive). One buffer is implemented in the FILE
structure and the other is implemented in the kernel.
Often, the FILE
structure buffers the content in a buffer inside of your program. When you write something to a buffered file, the content is keep in the buffer, inside of the running program. It is written to the OS when the buffer is full and, when the buffering mode is line buffered, at the end of a line. This data is written to the OS by a syscall, for example write()
.
The buffer is there because a syscall requires a context switch from the user program to the kernel, this is relatively expensive (slow), the buffer is here to reduce the number of syscalls. You could also use the syscalls from your program directly without the stdio
functions, however, this functions are less portable and more complex to handle.
A fflush(stdout)
checks if there are any data in the buffer that should be written and if so, the underlying syscall is used to write the data to the OS.
When the syscall returns, the data is in your kernel. But modern operating systems buffer this data as well. This is used to reduce the number of disk writes, reduce latency and other things. This buffer is completely independent of the FILE
buffer inside your program.
Note that this does not apply to all systems. For example microcontroller environments may provide some stdio.h
functions that write directly to a UART, without any buffer, neither inside FILE
nor any (probably non-existent) OS.
To see what fflush()
does to a running program, compare this programs:
int main(void)
{
fputs("s",stdout);
fputs("e",stderr);
}
and
int main(void)
{
fputs("s",stdout);
fflush(stdout);
fputs("e",stderr);
}
On Linux, stderr
is not buffered by default, so fputs("e",stderr);
will print the data immediately. On the other hand, fputs("s",stdout);
is line buffered by default on Linux so the data is not printed immediately. This causes the first program to output es
and not se
, but the second one outputs se
.
You can change the buffer modes with setvbuf()
stdout
will be flushed upon program termination, so, in this case you'll not notice any difference between the two programs.fflush(stdout)
is redundant here. – Kalaskyprintf
and thefflush
then you'll see a difference. – Systemreturn 0;
in both programs..." – Kalasky