答えは、使用している(またはコンパイラが使用している)C++標準のバージョンによって異なります。
C ++ 2003 5.2.2 p8によると:
引数の評価の順序は指定されていません。引数式の評価のすべての副作用は、関数に入る前に有効になります。後置式と引数式リストの評価順序は未定です。
これは、評価との間にシーケンスポイントがないことを意味します。f(x)
args
C ++ 2011では、シーケンスポイントの概念全体が置き換えられ(N1944を参照)、その表現は単なるメモになりました。
[注:接尾辞式と引数式の評価はすべて、相互に順序付けられていません。引数式の評価のすべての副作用は、関数に入る前に順序付けられます(1.9を参照)。—エンドノート]
と1.9p15は言う
関数を呼び出すとき(関数がインラインであるかどうかに関係なく)、引数式、または呼び出された関数を指定する後置式に関連するすべての値の計算と副作用は、本体のすべての式またはステートメントの実行前にシーケンスされます。関数と呼ばれます。[注:異なる引数式に関連する値の計算と副作用は順序付けられていません。—エンドノート]
これは、式f(x)
と式args
がの本体のすべての前にg
順序付けられているが、それらは相互に順序付けられていないことを示しています。これは、C ++ 03の規則と同じですが、言い回しが異なります。
C++14にはC++11と同じルールがありますが、以下のコメントに記載されているように、ルールはC++17で変更されました。
C ++ 2017 8.2.2 [expr.call] p5によると:
postfix-expressionは、expression-listの各式とデフォルトの引数の前にシーケンスされます。関連するすべての値の計算と副作用を含むパラメーターの初期化は、他のパラメーターの初期化に対して不確定に順序付けられます。
これは、あなたの例では、次のステップが順番に行われることを意味します。
f
評価されます。
x
が評価され、のパラメータf
が初期化されます。
- 関数呼び出し
f(x)
が評価されます。
f(x)->g
評価されます。
args
およびのその他の引数g
が評価され、のパラメータg
が初期化されます(指定されていない順序で)。
- 最後に、関数呼び出し
f(x)->g(args, ...)
が評価されます。