This is because of buffering. Stdout and stderr are usually buffered differently. Stdout is usually line buffered, meaning it will not display output until it sees a newline. Stderr is usually unbuffered and will print immediately, the thinking is you should see error messages pronto.
But they both go to the same place, the terminal. This is what it means by /* in case stdout and stderr are the same */
. They usually are. But because they're buffered differently this can lead to them being displayed out of order.
Consider this code. Note the lack of a newlines.
#include <stdio.h>
int main() {
fprintf(stdout, "This is to stdout. ");
fprintf(stderr, "This is to stderr. ");
fprintf(stdout, "This is also to stdout. ");
}
You'd expect the output to be:
This is to stdout. This is to stderr. This is also to stdout.
But it isn't. It's out of order.
$ ./test
This is to stderr. This is to stdout. This is also to stdout.
The output to stderr is displayed immediately, it is unbuffered. While stdout has to wait until the stdout buffer is flushed by a newline. There is no newline, so it is flushed when the program exits.
By flushing stdout before you use stderr you ensure that the output comes in the right order regardless of buffering.
#include <stdio.h>
#include <unistd.h>
int main() {
fprintf(stdout, "This is to stdout. ");
fflush(stdout);
fprintf(stderr, "This is to stderr. ");
fprintf(stdout, "This is also to stdout. ");
}
$ ./test
This is to stdout. This is to stderr. This is also to stdout.
This ensures that error messages come out in the right order along with normal messages. This avoids confusion about what error message applies to what part of the program.
This is also to stdout.
andThis is to stdout.
should be switched. – Virile