2011-01-17 3 views
0

Ich verwende die Streaming-Operatoren (z. B. operator<<(const char*)) für die Protokollierung. In meiner Unit-Tests Ich habe ein Test wie folgt aus:Wann werden Parameter berechnet, wenn ein verketteter Aufruf: obj.F1(). F2(). F3 (sin (x))?

MyLogger oLogger; 
oLogger << "charly"; 
oLogger << "foo" << sleep(10) << "bar"; 
oLogger << "marcus"; 

Zuerst habe ich einen zweiten Thread ausgeführt werden, die zur gleichen Zeit einzuloggen sollte. Ich frage mich, warum zwischen "foo" und "bar" keine andere Log-Ausgabe generiert wurde. Also habe ich in jedem Operator die aktuelle Uhrzeit ausgedruckt. Ich erwartete etwas wie folgt aus:

50 sec 137051 usec charly 
50 sec 137930 usec foo 
60 sec 138014 usec 0 
60 sec 138047 usec bar 
60 sec 138088 usec marcus 

bekam aber dies:

50 sec 137051 usec charly 
60 sec 137930 usec foo 
60 sec 138014 usec 0 
60 sec 138047 usec bar 
60 sec 138088 usec marcus 

Was mit folgender Idee falsch ist:

[ 0 sec] MyLogger& MyLogger::operator<<("charly") is processed. 
[ 0 sec] MyLogger& MyLogger::operator<<("foo") is processed. 
     The return value is used for the next function. 
[ 0 sec] int sleep(10) is processed - this takes 10 seconds until the return 
     value is available 
[10 sec] MyLogger& MyLogger::operator<<(0) is processed 
     ("0" is the return value of sleep(10)) 
[10 sec] MyLogger& MyLogger::operator<<("bar") is processed 

Aber aus welchem ​​Grund auch immer, die MyLogger::operator<<("foo") verarbeitet nach sleep(10)?

+0

Es scheint, dass es ist nichts Besonderes für Streams, wenn das gleiche Beispiel mit normalen Methoden zu schaffen, auch alle Parameter zuerst berechnet werden ...: s – Charly

+0

'Doppel x = 0; oClass.PrintAndIncrement (x) .Print (sin (x)); ' gibt' 0 0' aus, während 'double x = 0; oClass.PrintAndIncrement (x); oClass.Print (sin (x)); ' druckt' 0 0.841472'. – Charly

Antwort

1

Dies ist akzeptables Verhalten, da es in nicht angegeben ist, die Operanden um „Operator < <“ bewertet werden und TTBOMK gcc oft tut es in umgekehrter Reihenfolge für die die Parameter auf den Stapel in der richtigen Reihenfolge zu erhalten nächster Funktionsaufruf

Denken Sie daran, in Bezug auf eine Stapelmaschine:

push "charly" 
push oLogger 
call operator<< 
pop 
push "bar" 
push 10 
call sleep 
push "foo" 
push oLogger 
call operator<< 
call operator<< 
call operator<< 
pop 
Verwandte Themen