前回の記事「未定義の動作とシーケンス ポイント」では、に関連する潜在的な未定義の動作について説明しました。式:
i += ++i;
i が組み込み型の場合、オブジェクト i は連続するシーケンス ポイント間で 2 回変更されるため、この式は未定義の動作を呼び出します。
ただし、i がユーザー定義型 (定義された Index クラスなど) の場合以下:
class Index { int state; public: Index(int s) : state(s) {} Index& operator++() { state++; return *this; } Index& operator+=(const Index & index) { state+= index.state; return *this; } operator int() { return state; } Index & add(const Index & index) { state += index.state; return *this; } Index & inc() { state++; return *this; } };
式 i = i はまだ未定義の動作を呼び出しますか?
驚くべきことに、いいえです。ユーザー定義型 i の式 i = i は、オーバーロードされた演算子が C の関数とみなされるため、未定義の動作を引き起こしません。 C ISO 標準のセクション 1.9.17 によると:
関数を呼び出すとき (関数がインラインであるかどうかに関係なく)、すべての関数引数の評価後にシーケンス ポイントがあります...
したがって、演算子および演算子 = 関数の呼び出しにはシーケンス ポイントが導入され、未定義の動作が防止されます。
式 a[ i] = i は、 a がオーバーロードされた添字演算子を持つユーザー定義型である場合にも、 i 式の評価後にシーケンス ポイントを持つ関数呼び出しとみなされるため、適切に定義されています。 .
C 03 では、式 i は事実上同等であるため、明確に定義されています。 to:
((i.operator++()).operator++()).operator++();
各関数呼び出しでシーケンス ポイントが導入され、式が明確に定義されます。
以上がC では `i = i` は常に未定義の動作ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。