6

これは私が今日コーディングしたものです

#include <iostream>
using namespace std;

int function1()
{
  cout<<"hello from function1()"; return 0;
}

int function2()
{
  cout<<"hello from function2()"; return 0;
}

int main()
{
    int func_diffresult = 0;
    func_diffresult = function1() - function2();
    cout<<func_diffresult; /** prints 0 correctly **/
}

出力は get ishello from function2()hello from function1()です。出力は になるはずだと思いますhello from function1()hello from function2()。私のコンパイラは私と遊んでいますか?

4

3 に答える 3

11

-operatorの引数の評価順序は規定されていません。したがって、関数はどちらの順序でも呼び出すことができます。

于 2010-09-23T01:25:10.707 に答える
6

-演算子は事実上 になり、operator-(function1(), function2())関数パラメーターの評価順序は意図的に指定されていません。


関連ノート:

指定しないままにしておく十分な理由の 1 つは、呼び出し規則を効率的に処理するためです。たとえば、C の呼び出し規則では、パラメーターをの順序でスタックにプッシュする必要があります。

したがって、結果がすぐにプッシュされる可能性があるため、関数を逆の順序で評価することは理にかなっています。パラメータを左から右に評価し、結果を右から左にプッシュするには、結果をプッシュする前にすべての結果を保存する必要があります。本当にこれを行う必要がある場合は、手動で行うことができます。それが問題にならない場合でも、パフォーマンス上の利点はおそらく重要です。

于 2010-09-23T01:28:27.830 に答える
2

ISO 標準は、部分式が評価される順序を保証しません。

c++0x ドラフト標準から:


1.9。プログラムの実行:
      :
13/ Sequenced before は、単一のスレッドによって実行される評価間の非対称で推移的なペアワイズ関係であり、これらの評価の間に半順序を生じさせます。任意の 2 つの評価 A と B が与えられた場合、A が B の前に配列されている場合、A の実行は B の実行よりも優先されます。A が B の前に配列されておらず、B が A の前に配列されていない場合、A と B は配列されていません。[注: 順序付けされていない評価の実行はオーバーラップする可能性があります。]

られるか、B が A の前に順序付けられる場合、評価 A と B は不定に順序付けられますが、どちらが指定されていません。[注: 不確定な順序の評価はオーバーラップできませんが、どちらかが最初に実行される可能性があります。]
      :
15/特に明記されていない限り、個々の演算子のオペランドおよび個々の式の部分式の評価は順不同です。
     :
関数を呼び出すとき (関数がインラインかどうかに関係なく)、すべての値の計算と引数式、または呼び出された関数を指定する後置式に関連付けられた副作用は、本体内のすべての式またはステートメントの実行前に順序付けられます。呼び出された関数[脚注: つまり、関数の実行は互いにインターリーブしません] . [注: 異なる引数式に関連する値の計算と副作用は順序付けされていません。]

呼び出された関数の本体の実行の前または後に特に順序付けされていない呼び出し側関数 (他の関数呼び出しを含む) 内のすべての評価は、呼び出された関数の実行に関して不定に順序付けられます。


つまり、実装は、必要なメソッドを使用して呼び出しを自由に調整できます。ただし、関数呼び出しは脚注に従って特別に扱われます - それらはインターリーブしません。

于 2010-09-23T02:28:15.340 に答える