Can anyone explain the concept of stander error in C? I was told that anything that's sent to stderr isn't buffered.
Printable View
Can anyone explain the concept of stander error in C? I was told that anything that's sent to stderr isn't buffered.
Well, let's begin with the underlying file descriptors. fd 0 is by default connected to the standard input, fd 1 to the standard output and fd 2 to the standard error. As with any file descriptors, nothing sent to or received from them is ever buffered (except for standard input, where the terminal driver's line discipline will buffer a line if icanon is set).
At process startup, libc creates three FILE structures, each referring to each of these file descriptors. The entire purpose of FILE structures and stdio is to create a standard interface for buffering file data. stdout is by default line buffered (meaning the contents of the buffer is only flushed to the file descriptor when a newline is "sent" to it or when it's closed (or when fflush is called on it)). stderr is completely unbuffered, though, so that any error messages will be displayed immediately for the user to see.
Was there anything more about it?
Actually, I was just testing this in C. Since stderr isn't buffered, I thought that these messages would appear first out of any.
I thought the output would read STDERR, STDOUT 1, STDOUT 2, STDOUT 3 but the order doesn't appear this way. Instead, they are output as the function fprintf are called.Code:#include <stdio.h>
int main()
{
fprintf( stdout, "STDOUT 1\n" );
fprintf( stdout, "STDOUT 2\n" );
fprintf( stderr, "STDERR\n" );
fprintf( stdout, "STDOUT 3\n" );
return 0;
}
Naturally. Like I said, stdout is flushed if you attempt to send a newline over it. Try this instead:
I haven't actually tried it, but if I'm correct, it should give you something like this:Code:#include <stdio.h>
int main(void)
{
fprintf(stdout, "STDOUT 1 ");
fprintf(stderr, "STDERR 1 ");
fprintf(stdout, "STDOUT 2\n");
fprintf(stderr, "STDERR 2\n");
}
Code:STDERR 1 STDOUT 1 STDOUT 2
STDERR 2
Hmm. I wasn't aware that newline flushed the buffer. Does that also apply to the cout << operator? I know that using endl will flush the buffer but I'm not sure if appending a newline character to a string will flush the buffer without endl.
Well, you know, I really don't know how C++ works that well, and never once in my life have I used its iostreams. But as far as I know (which isn't very far, but anyway), iostreams are just front-ends to a FILE structure.
Dolda, are you saying I don't need to call fflush(NULL) to flush stderr if the string I'm printing ends with a newline?
I wasn't aware of that. Nice tip. I'm going to have to test it of course... ;-)
You don't have to flush stderr at all. All you might need to flush is stdout, and yes, that is only if your output doesn't end with a newline. stderr, on the other hand, is always completely unbuffered.
I just finished testing this out. As always, Dolda is right. I remember when I first wrote a program in C, I used a case structure and I was having problems with the printf(). Messages were being printed in a strange order (wasn't using stderr) and now that I think about it, it's because I wasn't appending the newline character. Of course the string "Enter a choice: \n" isn't appealing since the user would enter his/her choice on a newline so I believe I used fflush to get rid of the side effect.
If you want to, you can turn off buffering on stdout with this:
See the setvbuf(3) man page for details.Code:setvbuf(stdout, NULL, _IONBF, 0);