5

C はシーケンス ポイントの概念を使用してあいまいな計算を識別し、その=演算子はシーケンス ポイントではないことを理解しています。ただし、ステートメントの実行にあいまいさは見られません

i = ++i

私の理解では、これは単純に にあるものを評価し&i、それをインクリメントして、同じ場所に戻すことになります。それでも、GCC は次のようにフラグを立てます。

[警告] 'i' に対する操作は未定義の可能性があります [-Wsequence-point]

=どのように機能するか について何かが欠けていますか?

編集: 重複としてマークする前に、シーケンス ポイントと未定義の動作に関する他の投稿を閲覧したことに注意してください。それらのどれも具体的に式に対処していません( prei=++i -incrementに注意してください)。言及されている表現は一般的に、 などです。私はそれらのいずれについても疑いの余地はありません。i=i++a=b++ + ++b

4

2 に答える 2

7

未定義の動作について何かが欠けています。未定義の動作とは、コンパイラが必要なことを何でもできることを意味します。エラーをスローしたり、(GCC と同様に) 警告を表示したり、悪魔が鼻から飛び出したりする可能性があります。主なことは、うまく動作せず、コンパイラ間で一貫した動作をしないことです。そのため、実行しないでください!

この場合、コンパイラーは、ステートメントの rhs が返される前に、演算子の lhs の副作用が完了する必要があることを保証する必要はありません。これはあなたにはおかしいように見えますが、あなたはコンピューターのようには考えていません。必要に応じて、戻り値を計算してレジスタに返し、それを i に割り当ててから、実際の値をインクリメントすることもできます。だからそれはもっと似ているだろう

register=i+1;
i=register;
i=i+1;

標準では、これが起こらないという保証はありません。

于 2014-11-12T19:06:01.430 に答える