4

The following C++ code works fine when compiling with g++ on Ubuntu 18.04:

#include <iostream>

using namespace std;

void wait(){
  int t0 = time(0);
  while(true){
    if(time(0) >= t0 + 1){
      return;
    }
  }
}
int main(){
  while(true){
    cout << "tick\n";  //Line 15
    wait();
  }
}

This is the output where one tick appears every second:

tick
tick
tick
tick
tick

However when removing the \n in line 15 it seems to just be stuck somewhere and nothing happens. What exactly is \n doing to the code? What do I do if I don't want to print in a new line after every cycle? (I assume that calling this a bug in C++ would be a bit arrogant and wrong)

Also, I know that this is probably a very bad way of building a delay function, I'm just messing around a bit.

EVARATE
  • 115
  • 1
  • 1
  • 9
  • 1
    It's possible your output window only prints lines, so it's waiting for a newline before printing it. Doesn't mean your 'tick' isn't added to your output stream though. – Bas in het Veld Feb 04 '20 at 07:24
  • 2
    It's stuck in the stream's output buffer. On some systems the `'\n'` forces the stream to flush the buffer to the underlying medium, the console in this case. This is done because flushes can be expensive. You generally don't want to flush until you have to, to show the user some output for example . – user4581301 Feb 04 '20 at 07:24
  • 2
    Quick better way to to the wait: [`std::this_thread::sleep_for`](https://en.cppreference.com/w/cpp/thread/sleep_for) or it's buddy [`std::this_thread::sleep_until`](https://en.cppreference.com/w/cpp/thread/sleep_until). Which one you want depends on how you want to wake up, Every period or at a specific time, respectively. – user4581301 Feb 04 '20 at 07:27
  • 1
    Here is explained how to use std::flush in similar case https://stackoverflow.com/questions/22026751/c-force-stdcout-flush-print-to-screen – Adam Mierzwiak Feb 04 '20 at 07:29
  • 1
    More handy reading: [std::cout won't print](https://stackoverflow.com/questions/14858262/stdcout-wont-print) – user4581301 Feb 04 '20 at 07:35
  • Removing puts it all on 1 line. Are you sure that you're not seeing the correct output just squished onto the same line? –  Feb 04 '20 at 07:44
  • And more on `std::cout` buffering : [Is std::cout buffered?](https://stackoverflow.com/questions/26975876/is-stdcout-buffered). – Sander De Dycker Feb 04 '20 at 07:51

1 Answers1

10

It seems that your implementation of std::cout writes to the C output stream stdout. And stdout is by default (when connected to a terminal) line-buffered.

Line-buffering means that output is buffered internally, until a newline ('\n') is added to the buffer. Then the buffer is flushed and actually written to the terminal.


You can explicitly flush the buffer by using the C++ I/O manipulator std::flush, as in

cout << "tick" << std::flush;

That will immediately flush the buffer and write it to the terminal. But without a newline. To add a newline you could use std::endl:

cout << "tick" << std::endl;  // Add newline and flush

But note that the explicit extra flush isn't needed here, as the newline itself flushes the buffer. Using std::endl will therefore first flush the buffer once because of the newline, and then flush the empty buffer because of the explicit flushing semantics.

It's recommended that you don't use std::flush (or std::endl) unless you really have to. In most cases it's not really needed.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 2
    Adding a bit about `std::flush` and `std::endl` would improve the answer, I believe. – Jesper Juhl Feb 04 '20 at 07:29
  • 2
    See also [How does std::flush work?](https://stackoverflow.com/questions/14105650/how-does-stdflush-work) for details of when line-buffers are automatically flushed. – David C. Rankin Feb 04 '20 at 07:34