x = y = z = 1;
z = ++x||++y&&++z;
演算子の優先順位は次のとおりです --
(pre-increment) > && > ||
答えは--
1. 2||2 && 2
2. 2||1
3. 1
print x,y,z should be 2,2,1
しかし、答えは 2,1,1 です。
x = y = z = 1;
z = ++x||++y&&++z;
演算子の優先順位は次のとおりです --
(pre-increment) > && > ||
答えは--
1. 2||2 && 2
2. 2||1
3. 1
print x,y,z should be 2,2,1
しかし、答えは 2,1,1 です。
式にシーケンス ポイントはありません。
z = ++x || ++y && ++z;
のプレインクリメントとへのz
割り当ての間z
。
したがって、++z
が実際に評価されると、すぐに未定義の動作領域に入り、何かが起こる可能性があります。間にシーケンス ポイントがなければ、同じオブジェクトを 2 回変更することはできません。付録 C (C99 から) にはすべてのシーケンス ポイントがリストされており、ここで制御するものは完全な式 (計算と代入全体) に従っています。
6.5 Expressions /2
状態:
前のシーケンス ポイントと次のシーケンス ポイントの間で、オブジェクトの格納値は、式の評価によって最大 1 回変更されます。さらに、以前の値は、保存する値を決定するためにのみ読み取られます。
ただし、この特定のケースでは、初期値がx
1 の場合、式の一部は評価されません。開始点がand++z
の場合に UB が呼び出されるため、式自体の危険性が低下するわけではありません。x == -1
y != -1
この場合、標準の制御部分は次の6.5.14 Logical OR operator /4
とおりです。
ビットごとの | とは異なります。演算子、|| 演算子は左から右への評価を保証します。最初のオペランドの評価の後にシーケンス ポイントがあります。最初のオペランドが 0 と等しくない場合、2 番目のオペランドは評価されません。
そのため、++x
が最初に評価され、非ゼロと評価されるため、評価されること++y && ++z
はありません。x
は にインクリメントさ2
れz
、 の「真の」値に設定されます。 または1
は のy
まま1
です。