6
#include <iostream>                                                             

using namespace std;

int main()
{
   cout << 1;
   while (true);
   return 0;
}

I thought that this program should print 1 and then hung. But it doesn't print anything, it just hungs. cout << endl or cout.flush() can solve this problem, but I still want to know why it's not working as expected :) This problem appeared during codeforces contest and I spent a lot of time on looking at strange behavior of my program. It was incorrect, it also hunged, hidden output was actually debug information.

I tried using printf (compiling with gcc) and it behaves as well as cout, so this question can be referred to C also.

3 Answers3

8

You writing to a buffer. You need to flush the buffer. As @Guvante mentioned, use cout.flush() or fflush(stdout) for printf.

Update:

Looks like fflush actually works with cout. But don't do that - it may not be the fact in all cases.

Eugene
  • 8,611
  • 2
  • 26
  • 28
  • Can you explain why it flushes without `while(true);`? – Artem Ohanjanyan Aug 09 '13 at 20:09
  • I mean `printf` and C, not C++. – Artem Ohanjanyan Aug 09 '13 at 20:09
  • 1
    All buffers are flushed when process terminates. – Eugene Aug 09 '13 at 20:13
  • Note that if you would print a character in every `while` cycle you would occasionally see the output as the buffers would be filled from time to time. – Eugene Aug 09 '13 at 20:15
  • Is it some feature of `main()` function? `Cout` is probably flushed during destruction, but there are no objects in C. – Artem Ohanjanyan Aug 09 '13 at 20:25
  • 1
    @ArtemOhanjanyan it's not specific to main. It's just that process terminates after main is exited. That's when all cleanups happen, including buffers flush. – Eugene Aug 09 '13 at 20:33
  • 1
    @ArtemOhanjanyan: Actually, no. `cout` uses the same buffer as `printf`, which can be set with [`setbuf`](http://linux.about.com/library/cmd/blcmdl3_setbuf.htm). When you exit main, you will automatically close all pipes (stdin, stdout, stderr), which will result in the buffer being flushed. – Zeta Aug 09 '13 at 20:33
  • 1
    @Zeta chances are ostream actually does flush on destruction - but this doesn't matter in this case. – Eugene Aug 09 '13 at 20:39
  • @Zeta: So it's connected to `main()`, isn't it? :) – Artem Ohanjanyan Aug 09 '13 at 20:40
  • 1
    @ArtemOhanjanyan: C runtimes still support cleanup functions of some kind. See `atexit` for a standard example; many platforms have additional non-standard mechanisms. The C runtime will generally set things up using such means so that buffer flushes and so on will happen when the process exits, completely regardless of whether it exits via returning from main, calling `exit`, or some other means. It isn't too hard to construct particularly uncommon cases where `printf` output is not flushed at all if you know how your platform's underlying C runtime works. – Sean Middleditch Aug 09 '13 at 20:44
  • @claptrap I posted answer first, it's just when I thought about refining the answer I noticed that information is also in another answer. There were several upvotes even before I refined the answer. – Eugene Aug 09 '13 at 21:50
2

That is because cout buffers output. You have to flush the buffer for it to actually print.

endl and flush() both perform this flushing.

Also note that your program hangs because you have an infinite loop (while(true);).

The reason it does this is so that if you are printing a lot of data (say 1000 numbers) it can do so drastically more efficiently. Additionally most minor data points end with endl anyway, since you want your output to span multiple lines.

Guvante
  • 17,681
  • 1
  • 28
  • 64
  • 1
    The wording of the question to me suggests that the infinite loop was intentional. – SirGuy Aug 09 '13 at 20:06
  • @GuyGreer: I agree, but since the `;` is easy to miss felt the need to include that bit. Especially given the "I got this code from somewhere" notice. – Guvante Aug 09 '13 at 21:13
1

Concerning printf, the same as cout holds: you're printing into a buffer, you need to flush it with fflush(stdout);. Termination will flush the buffer, this is why you can see the output without your infinite loop.

See Why does printf not flush after the call unless a newline is in the format string? for more information.

Community
  • 1
  • 1
Zeta
  • 95,453
  • 12
  • 173
  • 214