Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the order is not preserved when printing something, first with cerr and then cout?

Tags:

c++

std

I have g++ version 4.8.4 compiler with Xubuntu 14.04. In the midst of my OpenCV code (written in Eclipse CDT), I wrote the following three lines consecutively:

/* Some codes here*/
cerr << "No match found. # of false positives: " << falsePositives << endl;
cout << "Press a key to continue..." << endl;
waitKey(0);

and here is the result:

Press a key to continue...
No match found. # of false positives: 1
/*there is a blank line*/

Why the order of those two lines changed at the execution time? There is no parallel code at all in the previous lines but they seems to work like parallel (at the same time).

I know that cerr is not buffered whereas cout is buffered (which means, afaik, cerr is slower compared to cout); however, no matter what, shouldn't the order of execution be changed? And where does that blank line comes from? (probably from one of those endls but which one?)

Can someone explain what is going on those two lines?

Thank you so much.

EDIT: I don't use ubuntu, I use Xubuntu 14.04. Sorry for that mistake, my mind was too messy but I think it does not effect the result. I use Eclipse's provided console to display them. I tried to append std:: prefix to all cout, cerr, endl. The result is same.

The interesting point is that when I just wrote a new file including:

#include <iostream>
#include <cstdlib>
int main()
{       
    std::cerr << "No match found. # of false positives: " << 2 << std::endl;
    std::cout << "Press a key to continue..." << std::endl;

    return 0;
}

I got the expected output(first cerr and then cout) by using xfce4-terminal and g++ compiler.

The problem occurs when using Eclipse CDT. I also want to remind all of you that I work on OpenCV.

Chris Dodd's 4th suggestion:

"your code is actually something other than what you've posted above, and the difference, while seemingly unimportant, is actually crucial."

Of course my code does contain other than what I typed but there are lots of, I mean lots of computation etc. before those lines. However, there might be relating parts before which I could not realise. Also, I didn't redirected stdout and/or stderr to different devices/files/pipes before those lines at all.

EDIT 2: When I execute the program in the Debug mode of Eclipse CDT, following assembly lines,

After cerr line the followings are executed (as well as other assembly codes of course):

callq 0x403500 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
callq 0x403470 <_ZNSolsEi@plt>
callq 0x403770 <_ZNSolsEPFRSoS_E@plt>

After cout line the followings are executed (as well as other assembly codes of course):

callq 0x403500 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
callq 0x403770 <_ZNSolsEPFRSoS_E@plt>
callq 0x403670 <_ZN2cv7waitKeyEi@plt>

and they all give the same error message:

No source available for "std::basic_ostream >& std::operator<< >(std::basic_ostream >&, char const*)@plt at 0x403500"

and the process continues with other lines of assembly code without termination.

PS: When I commented out everthing but those two lines, it works as expected. Thus, my conclusion is that, there may be relevant code part before those lines but I couldn't figure them out.

like image 672
Aka Avatar asked Jun 17 '16 14:06

Aka


Video Answer


1 Answers

std::cerr and std::cout are different streams and they are not synchronized. So you really can't assume anything about how output to both gets shown. In this case, the output happens to be shown before the error.

You can rely on the order within either stream.

Additionally, std::cout is buffered and std::cerr is not, and that often causes this kind of problem, but because you are using std::endl (which flushes the stream) this doesn't really apply in your case.

like image 56
Jesper Juhl Avatar answered Sep 19 '22 11:09

Jesper Juhl