2011-01-17 3 views
0

ストリーミングオペレータ(例:operator<<(const char*))をログに記録します。私の単体テストでは、次のようなテストがあります。連結されたコールを持つときにパラメータが計算されるとき:obj.F1()。F2().F3(sin(x))?

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

最初に2番目のスレッドを実行しました。同時に2番目のスレッドが実行されます。 "foo""bar"の間に他のログ出力が生成されなかった理由は不思議でした。そこで、私は各オペレータに現在の時刻を表示しました。私はこのような何か予想:

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 

をこれだ:

次の考えが間違っている何
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 

[ 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 

しかし、これまでどのような理由のために、MyLogger::operator<<("foo")が後に処理されsleep(10)

+0

...、それはストリームのための特別な何もないと思われます。■ – Charly

+0

'double x = 0; '0 x' 0 を出力しますが、 'double x = 0; oClass.PrintAndIncrement(x).Print(sin(x));' は '0 0'を出力します。 oClass.PrintAndIncrement(x); oClass.Print(sin(x)); ' は' 0 0.841472'を出力します。 – Charly

答えて

1

"オペレータ< <"のオペランドの順序が指定されていないため、TTBOMK gccは逆の順序でスタックに正しい順序でパラメータを取得することがよくあります次の関数呼び出し。スタックマシンの観点から、それの

思う:すべてのパラメータが最初に計算されても、通常の方法で同じ例を作成するときに

push "charly" 
push oLogger 
call operator<< 
pop 
push "bar" 
push 10 
call sleep 
push "foo" 
push oLogger 
call operator<< 
call operator<< 
call operator<< 
pop 
関連する問題