簡體   English   中英

一元 & 運算符能否產生地址 0(空指針)?

[英]Can the unary & operator yield the address 0 (null pointer)?

C2x,6.5.3.2 地址和間接運算符,語義,3:

一元 & 運算符產生其操作數的地址。

一個簡單的問題:一元運算符&可以產生地址0 (空指針)嗎?

有什么例子/經驗嗎?

它可以。 但是您必須 go 才能使它成為可能。

對於實際的 object,有兩種方法可以做到這一點:

  1. 構造一個 object 文件或 linker 符號文件,您要鏈接到該文件,並在 NULL 處導出一個符號。如果您 & 在上面,您將得到 NULL。

  2. 在某些平台上是 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM