2013-08-29 31 views
7

これはまた別のシーケンス点の質問ですが、かなりシンプルなもの:関数呼び出しからのシーケンスポイント?

#include <stdio.h> 
void f(int p, int) { 
    printf("p: %d\n", p); 
} 

int g(int* p) { 
    *p = 42; 
    return 0; 
} 

int main() { 
    int p = 0; 
    f(p, g(&p)); 
    return 0; 
} 

はこの未定義の動作ですか?または、g(&p)への呼び出しがシーケンスポイントとして機能しますか?

答えて

9

いいえが定義されていません。の動作です。関数の引数が評価される順序は、標準では指定されていないので、は指定されていません。です。したがって、コンパイラによって決定された評価順序に応じて、出力は0または42になります。

+6

また、 'g(&p)'がシーケンスポイントとして機能するかどうかを質問します。 'g(&p)'の評価には、 'g 'の評価と'&p'の評価の間、 ''フル表現 '' * p = 42; 'と' ' 'return'の中で' 0'を返します。しかし、どちらも 'g(&p)'の評価に関して引数 'p'の評価を命じていません。 –

+0

@EricPostpischil:素晴らしいコメントです。 :-) – Nawaz

4

我々は関数の引数の評価の順序を知らないので、プログラムの動作が指定されていない、draft C++ standard1.9プログラム実行パラグラフ3から:の

他の特定の局面および操作抽象機械は、この国際規格に不特定のものとして記述されている(例えば、関数への引数の評価の順序)。可能であれば、この国際標準は許容される行動のセットを定義する。 [...]

と機能が入力される前に、引数からすべての副作用はセクション5.2.2関数呼び出し段落8から、配列決定される:

[注:後置の評価式と引数式の順序は、すべて互いに順序付けされていません。 引数式評価のすべての副作用は、関数が入力される前にシーケンス化されます(1.9参照)。 -end注] C両方の点が節でC99 draft standardで覆われているとして

6.5.2.2関数呼び出し段落10

関数指定子の評価のため、実引数、および 実際の引数内の部分式は指定されていませんが、実際の呼び出しの前にはシーケンスポイント があります。

のでCC++の両方で、あなたはf(0,0)またはf(42,0)のいずれかで終わることができます。

関連する問題