2016-08-09 8 views
0

は、次のコードを考えてみましょう:関数の引数は左辺値に依存するため左辺値と関数結果依存関係?

int func(char *ptr); 
... 
n += func(p + n); 

は、このコード収率未定義の動作をしていますか?私は、コンパイラが関数の結果を計算し、次にp + nをインクリメントすると思います。これはおそらくコンパイラ固有のものでしょうか?

+0

@EugeneSh .:参照を追加してください。それは答えです。 –

答えて

2

関数呼び出しの前にシーケンスポイントがあります。これは、関数呼び出しで関数が入力される前に、すべての値の計算と引数に関連する副作用が完了したことを意味します。

C11-§6.5.2.2/ 10:

シーケンスポイントは、関数指定子の評価と実引数の後に実際の呼び出しの前にあります。

ので、

n += func(p + n); 

p + nの場合には、関数呼び出しの前に計算されます。

+0

* "引数が入力される前にすべての副作用が完了しました"という記述*は誤解を招くようです。ここにはどのように適用されますか?ここの副作用は何ですか? 'n 'のインクリメント?しかし、それは呼び出しの前に起こっていません。 'p + n'は' n 'の* previous *値で評価されます。 –

+0

@EugeneSh .;実際にはいくつかの情報が不足しているようです。この場合、 'p + n 'の値計算。 OPは言う:*私は、コンパイラが関数の結果を計算し、次に 'p + n' *をインクリメントすると仮定します。しかし、その反対は真です。 'p + n'が最初に計算され、関数はその結果を返します。 @EugeneSh .; – haccks

+0

; *表現AとBの評価の間にシーケンスポイント が存在することは、すべての値の計算と副作用の前に**すべての値の計算と の副作用**が順序付けされていることを意味します。 はBに関連付けられています*副作用だけでなく、abot値の計算についても同様です。この場合、引数に関連する副作用がないので、 'p + n'の値計算について話しています。 – haccks

0
n += func(p + n); 

は、nが関数呼び出しが完了した後にのみアクセスされるため、十分に定義されています。ファンクションコールは、nの値を読み取った後にのみ完了することができます。

+0

シーケンスポイントに関して、ここでそれらがまったく関係がある場合、どのように説明できますか?彼らはそうでないように見えます。ここに副作用はありません。 –

+0

@EugeneSh。関数呼び出しには引数の評価にのみ適用されるシーケンスポイントが含まれていますが、 'n + = func(p + n);がうまくいくかどうかを判断することは関係ありません定義された。 –