简体   繁体   中英

Why would I need use fflush on stdout before writing to stderr?

I am reading 'UNIX Network Programming: The Sockets Networking API' and in the example code they have an error handling function which contains the following lines:

fflush(stdout);     /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(stderr);

Where buf contains the error description. I don't understand why fflush is used on stdout on the first line and why the comment explains the reason for its use.

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.

如果stdout和stderr指向同一个文件,则必须确保首先写入stdout缓冲区中的任何内容。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM