我們有:
struct A {
int x;
int y;
} a;
假設:
offsetof(struct A, x) sizeof(int) == offsetof(struct A, y)
C標準(即C11)是否保證&a.x 1 == &a.y是真的?
如果不是,有沒有主流的編譯器保證?
此外,假設平等性得到滿足,a.y的值是否可以通過(&a.x)[1]訪問而不需要UB?
編輯
編輯
那么memcpy(&a.x 1, ...)呢?
uj5u.com熱心網友回復:
是的。C 2017 6.5.9討論了==和!=,它說:
6 兩個指標比較相等,當且僅當它們都是空指標,都是指向同一個物件(包括指向一個物件的指標和它開始的子物件)或函式的指標,都是指向同一個陣列物件最后一個元素之后的指標,或者一個是指向一個陣列物件結束后的指標,另一個是指向不同陣列物件開始的指標,而這個陣列物件在地址空間中剛好緊跟第一個陣列物件。7 就這些運算子而言,指向非陣列元素的物件的指標的行為與指向長度為1的陣列的第一個元素的指標的行為相同,該物件的型別為其元素型別。
根據第7段,a.x和a.y各自作為一個int的陣列,用于==。
由于offsetof(struct A, x) sizeof(int) == offsetof(struct A, y)保證a.y在地址空間中緊跟a.x,&a.x 1 == &a. y滿足第6段的最后一個條件,即一個是指向一個陣列物件結束后的指標,另一個是指向緊隨第一個陣列物件的不同陣列物件的指標。
此外,假設滿足了平等性,a.y的值是否可以通過(&a.x)[1]訪問而不需要UB?
不。&a.x 1等于&a.y的事實并不意味著它是&a.y。
這一點在標準中沒有完全或明確的說明。在有些情況下,指標運算必須能夠遍歷記憶體中相鄰的物件,特別是結構成員。例如,如果我們將一個結構的指標轉換為char *,我們可以用它來訪問結構中的各個位元組。我們可以用它來遍歷整個結構,包括成員。然后,如果我們適當地增加它以指向某個成員,并將它轉換回該成員型別的指標,我們應該有一個指向該成員的指標。
然而,C標準是用自然語言寫成的,并不完全是用形式邏輯或數學的符號(盡管有一些),所以它是不完整的,而且我們并不總是確定它所規定的內容。由于它沒有告訴我們&a.x 1可以用來訪問a.y,所以該行為是未定義的遺漏。
uj5u.com熱心網友回復:
可能與你的例子有關。ISO/IEC 9899:2018 (C17)在6.7.2.1#21談到了在結構的末尾訪問一個非指定大小的陣列:
struct s {
int n。
double d[];
};
//鑒于這個假設:
assert( sizeof (struct s) >= offsetof(struct s, d) sizeof (double) ) 。
//標準說,以下代碼可能是合法的,也可能是不合法的,。
//但是它并不是嚴格意義上的符合標準的代碼:。
struct s t1;
t1.d[0] = 4.2;
前面的例子與你的非常相似。所以我的猜測是:你想做的事情可能不是僭越(鑒于你用offsetof來檢查等),但你的代碼并不嚴格符合要求。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/315463.html
標籤:
