首頁 >後端開發 >C++ >即使對於使用者定義的類型,「i = i;」也是未定義的行為嗎?

即使對於使用者定義的類型,「i = i;」也是未定義的行為嗎?

Linda Hamilton
Linda Hamilton原創
2024-12-28 11:52:25773瀏覽

Is `i  =   i;` Undefined Behavior Even with User-Defined Types?

未定義的行為和序列點:深入探討

表達式i = i;已被標記為調用未定義行為(UB ),但是如果i 的型別是使用者定義的(如提供的Index 類別所示)呢?

使用者定義型別和 UB

對於像 Index 這樣的使用者定義型別,表達式 i = i;仍算UB。這是因為使用者定義類型不會覆寫增量運算子的預設行為。 operator()和operator =()函數只修改Index物件的內部狀態,並不會建立任何序列點。因此,表達式在連續序列點之間修改物件兩次,從而產生 UB。

表達式的等價

表達式i.operator =(i.operator () );和i.add(i.inc());不等於原來的i = i;。在第一個表達式中,i.operator () 求值之後的序列點允許在 = 運算子求值之前修改 Index 物件。類似地,在第二個表達式中,成員函數 add 和 inc 不會修改連續序列點之間的物件。因此,這些表達式不會呼叫 UB。

表達式定義和序列點

表達式 i = i;確實是一個表達式,但其行為沒有明確定義。與表達式關聯的序列點的數量不取決於所涉及的操作數的類型。

數組下標(a[ i] = i)

表達式a [我]=我;當a 是內建類型的數組或a 是重載下標運算子的使用者定義類型時,在這兩種情況下也為UB。在這兩種情況下,首先計算 [ i] 表達式,它遞增 i 並傳回其遞增前的值。然後將該值用作數組的索引,如果索引越界,可能會導致 UB。

多次遞增操作( i)

表達式一;在C 03 中定義良好,並且與表達式((((i.operator ()) .operator ()).operator ()).operator ()).operator ()); 具有相同的行為。每個operator()呼叫都會傳回Index物件的引用,並且每個函數求值後的序列點確保該物件在連續的序列點之間僅被修改一次。

結論

總之,表達式i = i;且a[i]=i;為使用者定義的型別呼叫UB,即使這些型別提供重載運算符。 Index 物件上的多個增量操作是明確定義的,這表示序列點和序列點之間物件的修改次數與所涉及的操作數類型無關。

以上是即使對於使用者定義的類型,「i = i;」也是未定義的行為嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:CS-第 5 週下一篇:CS-第 5 週