0

I have the following code:

int main()
{
   printf("hello world");
   while(1);
}

Should hello world be printed. If yes, WHY ? If no, WHY ? I am using gcc on a linux machine to compile code.

ctrl-alt-delor
  • 6,726
  • 5
  • 30
  • 48

2 Answers2

6

We can't tell.

The standard output buffer may be flushed, but it may as well not be flushed.

In other words, the "hello world" will be stored in the standard output buffer, when this printf("hello world"); gets executed.

Then, because of while(1);, we will go into an infinite loop.

At that point, we can't determine whether the standard output buffer will be flushed or not. For example, in this Live demo, it doesn't, which is the most likely thing to happen, but it's not guaranteed in general.

Typically I would add a newline, to make sure that the message gets printed. Read more in Why does printf not flush after the call unless a newline is in the format string?

Another way to do it, is like this:

#include <stdio.h>
int main(){
  printf("hello world");
  fflush(stdout);
  while(1);
}

would force the standard output buffer to empty itself and direct whatever was stored in it, to standard output (typically your screen).

As @hyde said, you could stimulate this behavior with your original code, by having gdb flushing the buffer for you, for example. Read more in How to unbuffer stdout of legacy running binary without stdbuf and similar tools.


This might be a hypothetical scenario, but a lesson to be learned from this is that during debugging, many people use printf()s, in order to pinpoint where their program crashes for example.

Not flushing the output buffer may lead to false assumptions, since the programmer might think that the program crashed before this printf("here");, but that might not be the case, because of the reasons discussed above.

In other words, it might be true that "here" is not printed in standard output (e.g. screen), but that doesn't mean that the execution of our program didn't reach that printf().

gsamaras
  • 66,800
  • 33
  • 152
  • 256
  • I wonder if it is possible to easily generate a scenario, where the stdio buffer would be flushed? – hyde Dec 18 '18 at 07:34
  • Sure it is @hyde, updated my answer. (if I understood you correctly:) ) – gsamaras Dec 18 '18 at 07:36
  • Yeah, that way of course, but I meant without changing the source code, or needing to recompile. I found a related question which has some answers: https://stackoverflow.com/questions/45460998/how-to-unbuffer-stdout-of-legacy-running-binary-without-stdbuf-and-similar-tools – hyde Dec 18 '18 at 07:38
  • @hyde good idea, improved my answer! And reached 50k rep!!!!!!!!!! :D Thanks for the upvote hyde! – gsamaras Dec 18 '18 at 07:40
  • adding a `\n` also seems to flush the buffer without using the `fflush`. I am not sure if this behavior can be depended upon... – yashC Dec 18 '18 at 09:12
  • @yashC indeed, if you search my edit history, you'll see I tried to mention it. However, I couldn't back that up with the Live demo. Now, I found another answer that backs this up (plus to my experience), so answer improved, thanks! – gsamaras Dec 18 '18 at 09:16
2

In the ordinary course of events, the message won't be printed — at least on the majority of Unix-like platforms. The default output buffering is (normally) line buffering when the standard output is an 'interactive device' (the standard jargon for 'terminal'). Since you haven't printed a newline, there is no line to be flushed, so the output stays in the program's buffers. When you interrupt it, the output is not flushed.

Only if you set the output to 'no buffering' would you see the output, or if you do an explicit fflush(stdout) or fflush(0) before entering the loop, or you do the sensible thing and add a newline to the string that's printed in the first place.

setvbuf(stdout, NULL, _IONBF, 0);

(Full buffering, such as when you pipe the output to another program, pretty much guarantees you won't see the output too.)

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185