言語は、右辺の部分式func(&ptr)
が
*ptr = func(&ptr);
が最初に評価され、左側の部分式*ptr
が後で評価されます (これは明らかに予想どおりです)。左辺は、を呼び出す前にfunc
、最初に正当に評価できます。そして、これはまさにあなたの場合に起こったことです:*ptr
呼び出しの前に、ptr
まだ を指していたときに評価されましたx
。その後、割り当て先が確定しました(つまり、コードが に割り当てられることがわかりましたx
)。それが発生すると、変更ptr
しても割り当て先は変更されなくなります。
したがって、評価の順序が指定されていないため、コードの即時の動作は指定されていません。ただし、考えられる評価スケジュールの 1 つは、NULL ポインター逆参照を引き起こすことによって、未定義の動作につながります。これは、一般に動作がundefinedであることを意味します。
このコードの動作を C++ 言語でモデル化する必要がある場合、この場合の評価プロセスはこれらの重要なステップに分割できると言えます。
1a. int &lhs = *ptr; // evaluate the left-hand side
1b. int rhs = func(&ptr); // evaluate the right-hand side
2. lhs = rhs; // perform the actual assignment
(C 言語には参照がありませんが、内部的には代入の左辺の評価結果を格納するために「実行時にバインドされた左辺値」という同じ概念を使用します。) 言語仕様では、手順 1a と1b 任意の順序で発生します。1b が最初に発生することを期待していましたが、コンパイラは 1a から開始することを決定しました。