Each time I start the program, the message "This message 2" is displayed in a random order relative to other messages.
#include <stdio.h>
int main()
{
fprintf(stdout,"This is message 1\n");
fprintf(stderr,"This is message 2\n");
fprintf(stdout,"This is message 3\n");
return 0;
}
Examples:
Why is this happening and how to fix it?
CodePudding user response:
No randomness is displayed in the examples; both show message 2 first, and this is the result of deterministic behavior.
Per C 2018 7.21.3 7, the standard error stream is not fully buffered. This means it is either unbuffered (printed characters are sent as soon as possible) or line buffered (printed characters are sent when a new-line character is printed or sooner). Since "This is message 2\n"
ends with a new-line character, both the unbuffered and line buffered modes send it as soon as possible.
Also per 7.21.3 7, the standard output stream is fully buffered if and only if it can be determined not to refer to an interactive device. Thus, we have two possibilities:
- The stream can be determined to refer to an interactive device. Then it is not fully buffered, so it is unbuffered or line buffered, and the strings ending with new-line characters are sent as soon as possible.
- The stream can not be determined to refer to an interactive device. Then it is fully buffered, so the strings are held in a buffer until the buffer is full or a flush is requested, which occurs at normal program termination.
Thus the total behavior of the program when the output is going directly to an interactive device is that all strings are sent immediately, so the output will be:
This is message 1 This is message 2 This is message 3
And the total behavior of the program when the output is not going to an interactive device is that message 2 is sent immediately and messages 1 and 3 are held in a buffer until the end of the program, so the output is:
This is message 2 This is message 1 This is message 3
Both cases are deterministic, not random. The output shown in the question is evidence that the IDE is running the program with the standard output captured in some way and presented to the user indirectly (as through a pipe or a redirection to a temporary file) rather than sent directly to the display device.
This can be changed by manually inserting fflush(stdout)
calls where you want the standard output to be sent immediately to the associated device or file, or it can be changed by making the standard output stream line-buffered:
setvbuf(stdout, 0, _IOLBF, 0); // Must be before stdout is used.
(You could also use setvbuf
to make the standard error stream fully buffered, but that is inadvisable.)
If the IDE is capturing both the standard output stream and the standard error stream in the same way, this will result in the messages appearing in the 1, 2, 3 order. However, it is possible the IDE is capturing the streams separately and displaying the standard error results first, in which case changing the buffering will not change the display.
CodePudding user response:
This is what OpenAI ChatGPT had to say when fed just the body of the question with no other prompts:
In this code, the messages "This is message 1" and "This is message 3" are being printed to the
stdout
standard output stream, while the message "This is message 2" is being printed to thestderr
standard error stream. The order in which these messages are displayed may be different each time the program is run, because thestdout
andstderr
streams are usually buffered differently, and the messages may be printed in different orders depending on how the buffers are flushed.
I neither agree nor not disagree with this. I post it because it's just ... wow...