2017-12-27 283 views
1

我经历了几个有关std :: cout评估顺序的问题,并且我明白std :: cout的参数之间没有顺序点,但是我无法理解下面的代码是如何工作的:C++:cout和函数调用之间的评估顺序

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(); 

我的功能redirect_stdout()和restore_stdout(),使用DUP2调用将标准输出重定向到/ dev/null的,并恢复它回来。我期望屏幕上显示的唯一输出是“重定向到/ dev/null”。但是我看到的是“恢复标准输出回到标准输出”。

看起来,redirect_stdout()在其先前的语句之前正在运行。

只是为了完整性,这里有两种方法的定义:

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; 
} 

为什么我看不到第一COUT输出?

+4

我的水晶球说,这是因为你在重定向之前不要刷新。尝试使用'<< std :: flush'。 – HolyBlackCat

+0

标准的'基于iostreams'的类在内部使用很多缓冲。我不知道冲洗它们是否足够,或者如果这将永远是不确定的,但它是我开始的地方。 –

回答

1

在这两种情况下,答案都是“缓冲”。发送输出到cout时,直到缓冲区已满或直到刷新输出为止,才会将其发送到文件描述符1。

的解决方法是刷新输出:

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(); 

(而不是std::flush,你也可以使用std::endl它输出一个换行符并刷新输出)。