以下程式有效嗎?(從 ISO C 標準明確定義的意義上說,不僅僅是碰巧在特定的編譯器上作業。)
struct foo {
int a, b, c;
};
int f(struct foo *p) {
// should return p->c
char *q = ((char *)p) 2 * sizeof(int);
return *((int *)q);
}
它至少遵循一些明確定義使用指標的規則:
正在加載的值與存盤在該地址的型別相同。
計算指標的出處是有效的,通過添加偏移量從有效指標派生而來,該偏移量給出了仍在原始存盤實體中的指標。
結構中沒有元素型別的混合,這會生成填充以使元素偏移量不可預測。
但是我仍然不確定以這種方式顯式計算和使用元素指標是否有效。
uj5u.com熱心網友回復:
C是一種低級編程語言。此代碼定義明確,但可能不可移植。它不可移植,因為它對結構的布局做出了假設。特別是,您可能會在 64 位平臺上遇到 64 位對齊的欄位,其中 in 是 32 位。更好的方法是使用offsetof marco。
uj5u.com熱心網友回復:
C 標準允許在 a 的元素之間進行任意填充struct(但不是在一個的開頭)。現實世界的編譯器不會在類似的編譯器中插入填充struct,但DeathStation 9000是允許的。如果您想以便攜方式執行此操作,請使用offsetof()來自<stddef.h>.
*(int*)((char*)p offsetof(foo, c))
保證作業。差異,例如offsetof(foo,c) - offsetof(foo, b),也是明確定義的。(雖然,由于offsetof()回傳一個無符號值,如果差值下溢,它被定義為一個大的無符號數。)
在實踐中,當然,使用&p->c.
但是,只要您不超出緩沖區,就可以保證像原始問題中的運算式一樣適用于陣列元素。您還可以在陣列末尾生成一個指標,并將該指標與陣列中的指標進行比較,但取消參考這樣的指標是未定義的行為。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/532304.html
標籤:C指针未定义行为
上一篇:typedef定義的指標變數
下一篇:在C中洗掉雙向鏈表中的唯一元素
