[英]Can the unary & operator yield the address 0 (null pointer)?
C2x,6.5.3.2 地址和間接運算符,語義,3:
一元 & 運算符產生其操作數的地址。
一個簡單的問題:一元運算符&
可以產生地址0
(空指針)嗎?
有什么例子/經驗嗎?
它可以。 但是您必須 go 才能使它成為可能。
對於實際的 object,有兩種方法可以做到這一點:
構造一個 object 文件或 linker 符號文件,您要鏈接到該文件,並在 NULL 處導出一個符號。如果您 & 在上面,您將得到 NULL。
在某些平台上是 libc。 您定義的第一個符號是 NULL。至少在一個平台上,堆管理器必須應對此問題,因此對其進行了仔細編碼,以便編譯器永遠不會觀察到堆 HEAD 指針存儲在 NULL 的事實。
請注意,這兩個都在便攜式C之外,這就是重點。 如果你得到&
返回 NULL 你就會知道你做到了。 這不是偶然發生的。
但是還有另一種方法:我們可以構造一個不包含真實對象的表達式,其中&
返回 0。像這樣:
&(((struct some_struct *)0)->first_member)
只見於
#define offsetof(type, member) ((size_t)&(((type *)0)->member))
不要這樣做。 #include <stddef>
並讓編譯器定義offsetof
。 這個實現中有一個錯誤。
C 2018 6.5.3.2 1 說:
一元
&
運算符的操作數應為 function 指示符,[]
或一元*
運算符的結果,或指定 object 不是位域的左值……
If the operand is a function designator, it cannot be a null pointer, since C 2018 6.3.2.3 3 says a null pointer “is guaranteed to compare unequal to a pointer to any object or function,” but a function designator that were a null指針將與另一個(可能不同的)null 指針比較,因為 C 2018 6.5.9 6 表示兩個 null 指針比較相等。
如果它是指定 object 的左值,則出於同樣的原因,它不能是 null 指針。 (請注意,6.5.3.2 1 特指指定一個 object 的左值。通常,左值是一個可能指定一個 object 的表達式。也就是說,它必須具有 object 類型。但是,6.5.3.2 1 中的約束特別告訴我們操作數必須實際指定一個 object。)
剩下[]
或一元*
的結果。 前者是根據后者定義的,所以我們只需要考慮一元*
。 C 2018 6.5.3.2 2 說“一元*
運算符的操作數應具有指針類型”,但並不要求它指向實際的 object 或 function 或非空。 6.5.3.2 4 表示“……如果操作數指向 function,則結果為 function 指示符; 如果它指向 object,則結果是指定對象的左值……”但沒有明確說明如果操作數是 null 指針,結果是什么。 它繼續說“如果為指針分配了無效值,則一元*
運算符的行為未定義。” 那里的文本引用注釋 106,它說“......在一元*
運算符取消引用指針的無效值中,有一個 null 指針,一個地址與指向的 object 類型不適當對齊,以及 object 之后的地址生命周期結束。”
因此,C 標准沒有定義一元&
會產生 null 指針的行為。 當然,它可能通過標准未定義的行為發生。
該標准的相關部分是 6.3.2.3/3 (N2731),其中規定
如果將 null 指針常量轉換為指針類型,則生成的指針(稱為 null 指針)保證與指向任何 object 或 function 的指針比較不相等。
因此, &
作用於任何 object 的結果保證與 null 指針“比較不相等”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.