簡體   English   中英

當 (void *) p == (void *) *p - 標准對此有何評論?

[英]When (void *) p == (void *) *p - What does the Standard say about this?

例子:

int a[99];
int (*p)[99] = &a;

// this prints 1
printf("%d\n", (void *) p == (void *) *p);

通常,如果p是指向數組的指針,則p*p的對象表示(即位模式)是相等的。

我只是失去了,完全不能確定這種行為的便攜性。

所以,我很好奇這種行為是否受到標准的保證。 如果是這樣,有人可以引用所有保證它的相關段落嗎?

此比較保證為 1。

C 標准的相關部分是關於相等運算符和指針比較的第 6.5.9p6 節:

兩個指針比較相等當且僅當它們都是空指針,都是指向同一個對象的指針包括指向對象的指針和位於其開頭的子對象)或函數,都是指向同一數組最后一個元素之后的指針對象,或者一個是指向一個數組對象末尾的指針,另一個是指向另一個數組對象開頭的指針,該對象恰好緊跟地址空間中的第一個數組對象。

請特別注意粗體的段落。 這意味着兩件事:1)指向結構的指針和指向其第一個成員(合適的轉換)的指針將比較相等,2)指向數組的指針和指向其第一個成員的指針(再次,合適的轉換)將比較平等的。

在您的特定情況下, p指向一個數組, *p是數組本身,並且在表達式中使用*p產生一個指向其第一個成員的指針。 兩者都轉換為void *以賦予它們一個通用類型。 因此,這種比較將始終評估為 1。

通常,如果p是指向數組的指針,則p*p的對象表示(即位模式)是相等的。

如果p是指向數組的指針,則*p是數組。 數組的位表示是數組元素的位表示的串聯(因為 C 2018 6.2.5 20 說數組由連續分配的對象組成)。 數組中的位通常不等於指針中的位。

但是,當數組在表達式中用作一元&的操作數或sizeof的操作數或用於初始化數組的字符串文字以外的表達式時,該數組會自動轉換為指向其第一個元素的指針。 數組*p的第一個元素是(*p)[0] ,因此*p會自動轉換為&(*p)[0]

那么問題是(void *) p是否等於(void *) &(*p)[0]

C 2018 6.3.2.3 1 告訴我們任何指向對象類型的指針都可以轉換為void * 但是,當指針為void * ,它並沒有告訴我們比較的結果是什么。 它確實告訴我們,將void *轉換回其原始類型會產生一個與原始類型相等的指針。

C 2018 6.5.9 6 告訴我們“兩個指針比較相等當且僅當……,兩者都是指向同一個對象的指針(包括指向對象的指針和開頭的子對象)……”(我省略了其他一些情況這里無關緊要。)給定兩個void *我們該怎么做? 似乎意圖是讓指針“指向一個對象”,即使它當前是void *的形式。 然后(void *) p指向數組並且(void *) &(*p)[0]指向其開頭的子對象,因此它們比較相等。

使用(char *) p == (char *) *p的語義會更清晰,因為 C 2018 6.3.2.3 7 告訴我們轉換為char *會產生一個指向對象第一個字節的指針,以及一個指向對象的第一個字節的指針。數組與其第一個元素的第一個字節相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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