Unexpected sequence of cout / perror in console output
-
Could somebody please explain to me why I do not see the "perror" in expected code sequence? Thanks
int main() {
// modified from scan.c
// http://people.csail.mit.edu/albert/bluez-intro/c404.html
//cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
cout << "Basic bluetooth app BLUEZ_LINUX " << endl; // prints !!!Hello World!!!
inquiry_info *ii = NULL;/\* \* \* The inquiry\_info structure is defined as typedef struct { bdaddr\_t bdaddr; uint8\_t pscan\_rep\_mode; uint8\_t pscan\_period\_mode; uint8\_t pscan\_mode; uint8\_t dev\_class\[3\]; uint16\_t clock\_offset; } \_\_attribute\_\_ ((packed)) inquiry\_info; \* \* \* \* \*/
//HERE NEED TO INITIALIZE SOME OF THESE ??
int max_rsp, num_rsp;
int dev_id, sock, len, flags;
int i;
char addr[19] = { 0 };
char name[248] = { 0 };// Get bluetooth device id dev\_id = hci\_get\_route(NULL); // Passing NULL argument will retrieve the id of first avalaibe device
SHOULD PRINT PERROR HERE ??
if (dev\_id < 0) { //printf("Error: Bluetooth device not found"); perror("Error: Bluetooth device not found"); // adds perror "no such device " // exit(1); }
#ifdef DEBUG
cout << " dev_id = hci_get_route(NULL) " << endl; // prints !!!Hello World!!!
cout << " dev_id " << hex << +dev_id << endl; // prints !!!Hello World!!!
#endif#ifdef BYPASS // replaced with abpve perror
dev_id = hci_get_route(NULL); // what is valid dev_id ??#endif
sock = hci\_open\_dev(dev\_id);
#ifdef DEBUG
cout << " sock = hci_open_dev( dev_id ) " << endl; // prints !!!Hello World!!!
cout << " sock " << hex << +sock << endl; // prints !!!Hello World!!!
#endifif (dev\_id < 0 || sock < 0) { perror("Error: Opening socket"); //exit(1); }
#ifdef DEBUG
cout << " HERE @line " << dec << __LINE__ << endl; // prints !!!Hello World!!!
cout << " TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
#endif
// need desrtip[tion
len = 8;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;#ifdef DEBUG
cout << " HERE @line " << dec << __LINE__ << endl; // prints !!!Hello World!!!
cout << " TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
#endifii = (inquiry\_info\*) malloc(max\_rsp \* sizeof(inquiry\_info));
// not an error just checking but it exi6ts after second perror
#ifdef BYPASS
if (ii)
perror("Error: inquiry_info*");
if (ii)
perror("Error: inquiry_info*");
#endif#ifdef DE
-
Could somebody please explain to me why I do not see the "perror" in expected code sequence? Thanks
int main() {
// modified from scan.c
// http://people.csail.mit.edu/albert/bluez-intro/c404.html
//cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
cout << "Basic bluetooth app BLUEZ_LINUX " << endl; // prints !!!Hello World!!!
inquiry_info *ii = NULL;/\* \* \* The inquiry\_info structure is defined as typedef struct { bdaddr\_t bdaddr; uint8\_t pscan\_rep\_mode; uint8\_t pscan\_period\_mode; uint8\_t pscan\_mode; uint8\_t dev\_class\[3\]; uint16\_t clock\_offset; } \_\_attribute\_\_ ((packed)) inquiry\_info; \* \* \* \* \*/
//HERE NEED TO INITIALIZE SOME OF THESE ??
int max_rsp, num_rsp;
int dev_id, sock, len, flags;
int i;
char addr[19] = { 0 };
char name[248] = { 0 };// Get bluetooth device id dev\_id = hci\_get\_route(NULL); // Passing NULL argument will retrieve the id of first avalaibe device
SHOULD PRINT PERROR HERE ??
if (dev\_id < 0) { //printf("Error: Bluetooth device not found"); perror("Error: Bluetooth device not found"); // adds perror "no such device " // exit(1); }
#ifdef DEBUG
cout << " dev_id = hci_get_route(NULL) " << endl; // prints !!!Hello World!!!
cout << " dev_id " << hex << +dev_id << endl; // prints !!!Hello World!!!
#endif#ifdef BYPASS // replaced with abpve perror
dev_id = hci_get_route(NULL); // what is valid dev_id ??#endif
sock = hci\_open\_dev(dev\_id);
#ifdef DEBUG
cout << " sock = hci_open_dev( dev_id ) " << endl; // prints !!!Hello World!!!
cout << " sock " << hex << +sock << endl; // prints !!!Hello World!!!
#endifif (dev\_id < 0 || sock < 0) { perror("Error: Opening socket"); //exit(1); }
#ifdef DEBUG
cout << " HERE @line " << dec << __LINE__ << endl; // prints !!!Hello World!!!
cout << " TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
#endif
// need desrtip[tion
len = 8;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;#ifdef DEBUG
cout << " HERE @line " << dec << __LINE__ << endl; // prints !!!Hello World!!!
cout << " TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
#endifii = (inquiry\_info\*) malloc(max\_rsp \* sizeof(inquiry\_info));
// not an error just checking but it exi6ts after second perror
#ifdef BYPASS
if (ii)
perror("Error: inquiry_info*");
if (ii)
perror("Error: inquiry_info*");
#endif#ifdef DE
-
It does print the message at the bottom as you can see in the above output. Most likely because the
stderr
stream is not displayed until the application terminatesRichard MacCutchan wrote:
Most likely because the
stderr
stream is not displayed until the application terminatesI think that's because C++ IO streams and C stdio streams are no synchronized. Try using
stdi::ios_base::sync_with_sdio
. [std::ios_base::sync_with_stdio - cppreference.com](https://en.cppreference.com/w/cpp/io/ios\_base/sync\_with\_stdio) -
Richard MacCutchan wrote:
Most likely because the
stderr
stream is not displayed until the application terminatesI think that's because C++ IO streams and C stdio streams are no synchronized. Try using
stdi::ios_base::sync_with_sdio
. [std::ios_base::sync_with_stdio - cppreference.com](https://en.cppreference.com/w/cpp/io/ios\_base/sync\_with\_stdio) -
Not according to my tests, and ultimately cout (under the covers) will be printing to stdio/stderr in normal fashion.
Hmm.. I've compiled the OP's code and my own test code (below) and both times I get perror() and cout code interleaved. Not sure what I might be doing differently than the you guys. I've tried on both Fedora 29 (g++ v 8.3.1) and rpi (g++ v 6.3.0). Now I'm confused ...
$ cat errtest.cpp
\#include
\#includeusing namespace std;
int main()
{
for(errno= 0; errno < 4; ++errno) {
cout << "errno = " << errno << endl;
perror("Error");
}
}
$ make errtest
g++ -Wall -Wextra -std=c++17 -O2 errtest.cpp -o errtest
$ ./errtest
errno = 0
Error: Success
errno = 1
Error: Operation not permitted
errno = 2
Error: No such file or directory
errno = 3
Error: No such process -
Hmm.. I've compiled the OP's code and my own test code (below) and both times I get perror() and cout code interleaved. Not sure what I might be doing differently than the you guys. I've tried on both Fedora 29 (g++ v 8.3.1) and rpi (g++ v 6.3.0). Now I'm confused ...
$ cat errtest.cpp
\#include
\#includeusing namespace std;
int main()
{
for(errno= 0; errno < 4; ++errno) {
cout << "errno = " << errno << endl;
perror("Error");
}
}
$ make errtest
g++ -Wall -Wextra -std=c++17 -O2 errtest.cpp -o errtest
$ ./errtest
errno = 0
Error: Success
errno = 1
Error: Operation not permitted
errno = 2
Error: No such file or directory
errno = 3
Error: No such process -
Sorry, my previous comment was unclear (or incorrect). I do get
stdout
andstderr
correctly interleaved. I have a feeling that OP is using some weird stuff (cf Bluez questions). Interesting how your sample code matches mine quite closely.Only thing I can think of ATM is that the OP is running the code inside whatever terminal his IDE provides, and that's doing something odd with termio settings. I've tried messing with setvbuf() and various stty options, but always get interleaved output. That being said, it should be pointed out to the OP that stdout (cout) and stderr (cerr), are different output streams. If you take my code and remove the
<< endl
from line 9, then the output is quite different! -
Only thing I can think of ATM is that the OP is running the code inside whatever terminal his IDE provides, and that's doing something odd with termio settings. I've tried messing with setvbuf() and various stty options, but always get interleaved output. That being said, it should be pointed out to the OP that stdout (cout) and stderr (cerr), are different output streams. If you take my code and remove the
<< endl
from line 9, then the output is quite different!Really for the OP but I will put here to follow the discussion Someone is on a multicore processor and the streams which are buffering are on different cores with resource locks :-) This is generally not guaranteed to give the expected order
printf("Expect 1\n");
perror("Expect 2\n");
printf("Expect 3\n");Simply put two independent streams are not guaranteed to synchronize without you forcing the issue. In the above Expect1 will always be before Expect3 but Expect2 can be before, in the middle or after those two lines. sync_with_stdio() if implemented will work but it implies a heavy overhead on a many multicore situation which is why it might be off. I think it is supposed to default on with some c++ versions (but on multicore it is often violated because it is horrific) you would need to check with your compiler. The simple answer is stop using perror and simply just use one stream aka printf/cout, flush after each print or put lock primitives in the order to guarantee the order. It is easily avoidable ... so avoid it :-)
In vino veritas