との評価の順序が不定であるため、式を評価した結果はunspecifiedです。x
fun(&x, &y)
式の評価で不特定の結果が得られることは、プログラムに未定義の動作があることを意味しないことに注意してください。むしろ、可能な結果の有限集合のどれがその式の評価によって生成されるかを知ることができないことを意味します。
ここで標準を解釈するのは非常に難しい場合があります(実際、元の回答では、私はそれを間違った方法で解釈していました-気づいてくれたJerry Coffinに感謝します)。
これが難しい理由を理解するために、C++11 標準の段落 1.9/15 の最初の部分を考えてみましょう。
特に明記されていない限り、個々の演算子のオペランドおよび個々の式の部分式の評価は unsequencedです。[...] 演算子のオペランドの値の計算は、演算子の結果の値の計算の前に並べられます。スカラー オブジェクトに対する副作用が、同じスカラー オブジェクトに対する別の副作用、または同じスカラー オブジェクトの値を使用した値の計算に対して順序付けされていない場合、動作は undefinedです。
たとえば、次のような 2 つのサブ式の合計を計算する式があるとします (consideringoperator +
はここではオーバーロードされていません)。
e1 + e2
の評価でe1
特定のスカラーの値が使用され、s
の評価でe2
その値に副作用がある場合、動作は未定義です。たとえば、次の評価:
(i + i++)
上記の文により、未定義の動作が発生します。
ただし、状況は異なります。後の同じ段落では、次のように指定されています。
関数を呼び出すとき (関数がインラインであるかどうかにかかわらず)、[...] 呼び出された関数の本体の実行の前後に特に順序付けされていない呼び出し関数 (他の関数呼び出しを含む) のすべての評価は、呼び出された関数の実行に関して不定に順序付けられます。
これは、評価される式が次のようになっている場合を意味します。
i + f(i)
そしてf(i)
増加i
すると、動作は未定義ではなくなり、未指定のみになります。言い換えれば、コンパイラはi
andf(i)
を任意の順序で評価できますが、可能な結果はこれらの可能な評価の 1 つの結果にすぎません。
一方、動作が定義されていない場合、考えられる結果は何でもありました (クラッシュから、期待どおりの動作、コンソールへの奇妙なメッセージの出力などに至るまで)。