Aris totle
Aris totle

Reputation: 71

C++: Order of evaluation between cout and a function call

I went through few questions about std::cout evaluation order and I understand that there is no sequence point between the args of std::cout, however I am unable to understand how the following code works:

saved_fd = dup(STDOUT_FILENO);
std::cout << "Redirecting std out to /dev/null";
redirect_stdout()
<do some stuff>
std::cout << "Restoring std out back to standard output";
restore_stdout();

My functions redirect_stdout() and restore_stdout(), using the dup2 calls redirects standard output to /dev/null and restores it back later. I expect the only output to show up on screen is "Redirecting std out to /dev/null". But what I see is "Restoring std out back to standard output".

It appears that redirect_stdout() is getting run before its previous statement.

Just for completeness, here are the definitions of the two methods:

void redirect_stdout()
{
  dump_fd = open("/dev/null", O_RDWR, 0777);
  dup2(dump_fd, STDOUT_FILENO);
  cout << endl;
}

void restore_stdout()
{
  dup2(saved_fd, STDOUT_FILENO);
  cout << endl;
}

Why don't I see the first cout output?

Upvotes: 1

Views: 115

Answers (1)

In both cases, the answer is "buffering". When you send output to cout, it isn't sent to file descriptor 1 until the buffer is full, or until you flush the output.

The fix is to flush the output:

saved_fd = dup(STDOUT_FILENO);
std::cout << "Redirecting std out to /dev/null" << std::flush;
redirect_stdout()
<do some stuff>
std::cout << "Restoring std out back to standard output" << std::flush;
restore_stdout();

(Instead of std::flush, you could also use std::endl which outputs a newline and flushes the output.)

Upvotes: 1

Related Questions