在上一部分中,「未定義的行為和序列點」我們討論了與相關的潛在未定義行為表達式:
i += ++i;
當 i是內建類型時,此表達式會呼叫未定義的行為,因為物件 i 在連續序列點之間被修改兩次。
但是,如果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 是帶有重載下標運算子的使用者定義型別時,表達式a[ i] = i 也是明確定義的,因為在評估i 表達式後,它被視為帶有序列點的函數調用.
在 C 03 中,表達式 i 是明確定義的,因為它實際上是等價的to:
((i.operator++()).operator++()).operator++();
每個函數呼叫都會引入一個序列點,使表達式定義良好。
以上是C 中 `i = i` 總是未定義行為嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!