次のコードでは:
int foo();
int bar();
int i;
i = foo() + bar();
foo
呼び出される前に呼び出されることはC標準で保証されていbar
ますか?
次のコードでは:
int foo();
int bar();
int i;
i = foo() + bar();
foo
呼び出される前に呼び出されることはC標準で保証されていbar
ますか?
いいえ、 にはシーケンス ポイントはありません+
。実際、ウィキペディアのページには、あなたの質問に答える引用があります。
2 つの関数 f() と g() を考えてみましょう。C および C++ では、+ 演算子はシーケンス ポイントに関連付けられていないため、式 f()+g() では、f() または g() のいずれかが最初に実行される可能性があります。
それは特定されておらず、C99 の場合、関連する引用は 6.5/3 です。
後で指定する場合を除き (関数呼び出し
()
、、、、およびコンマ演算子について)&&
、部分式の評価の順序と副作用が発生する順序はどちらも指定されていません。||
?:
あなたの例では、foo()
andbar()
は完全な式の部分式i = foo() + bar()
です。
関数呼び出しの「後で」は、ここでは直接関係ありませんが、参考までに 6.5.2.2/10 です。
関数指定子、実引数、および実引数内の部分式の評価順序は指定されていませんが、実際の呼び出しの前にシーケンス ポイントがあります。
6.5.13 &&
/4 の場合:
ビットごとのバイナリ & 演算子とは異なり、&& 演算子は左から右への評価を保証します。最初のオペランドの評価の後にシーケンス ポイントがあります。
+
は上部の演算子のリストになく、&&
とが「似ていない」のと+
同じように「似ていない」ため、これはまさにあなたが求めていることです。とは異なり、は左から右への評価を保証しません。&&
&
&&
+
いいえそうではありません。関数と演算子の引数の評価順序は定義されていません。
標準は、関数呼び出しなしで部分式を評価するときに発生する可能性がある呼び出しとインターリーブできないことのみを述べてfoo
いbar
ます。
私が働いている場所の正解は、「順序が重要な場合、標準が何を言おうと、コードは保守できません」です。bar() の前に foo() を評価する必要がある場合は、bar() の前に foo() を明示的に評価します。これの根拠は、すべてのプログラマーが標準を知っているわけではなく、元の作成者が知っているかどうかを知らない人もいるということです。
いいえ、これは定義されていません。K & R 200 ページから:
部分式が副作用を伴う場合でも、式の評価順序は、特定の例外を除いて未定義です。つまり、演算子の定義がそのオペランドが特定の順序で評価されることを保証しない限り、実装は自由にオペランドを任意の順序で評価したり、評価をインターリーブしたりできます。
K & R の 205 ページには加法演算子が記述されており、2 つのオペランドの評価子の順序は定義されていません。