如果我理解正確,該程式在 C 中具有未定義的行為,因為中間值p 1是指向未初始化記憶體的指標:
int main () {
int x = 0;
int *p = &x;
p = p 1 - 1;
*p = 5;
}
如果void放在main的引數串列中(根據 C 語法的要求),它是否也是 C 中未定義的行為?
uj5u.com熱心網友回復:
沒有未定義的行為。您可以將單個物件視為具有一個元素的陣列。使用指標演算法,指標可能指向陣列最后一個元素之后的元素,所以這個陳述句
p = p 1 - 1;
是正確的。
來自 C 標準(6.5.6 加法運算子)
7 對于這些運算子,指向不是陣列元素的物件的指標與指向長度為 1 且物件型別作為其元素型別的陣列的第一個元素的指標的行為相同。
和
- ...此外,如果運算式 P 指向陣列物件的最后一個元素,則運算式 (P) 1 指向陣列物件的最后一個元素,如果運算式 Q 指向陣列物件的最后一個元素,則陣列物件,運算式 (Q)-1 指向陣列物件的最后一個元素。
注意那個
- ...如果指標運算元和結果都指向同一個陣列物件的元素,或者超過陣列物件的最后一個元素,則評估不應產生溢位;否則,行為未定義。
uj5u.com熱心網友回復:
我認為 OP 選擇p 1 - 1作為示例有點不幸,因為這不是莫斯科的回答p 1中的弗拉德所示的未定義行為。
如果我們考慮這個問題會更有趣p 2 - 2。這p 2確實是未定義的行為。但是,如果在完整運算式中我們“撤消此計算”,這是否重要。
有一個整數的類比。例如,給定i一個有符號整數,如果i 2溢位,因此是未定義的行為,運算式是i 2 - 2好的還是未定義的行為?
兩者的答案都是未定義的行為。如果一個運算式是未定義的行為并且程式將在其評估中到達該運算式,那么整個程式將表現出未定義的行為。
對此有一個更廣為人知的案例:計算有符號整數的中點:(a b) / 2如果溢位,則為 UB a b,即使最終值適合資料型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425194.html
上一篇:Phaser3多指標事件合二為一
