簡體   English   中英

比較不在同一數組定義行為的兩個指針上的相等性嗎?

[英]Is comparing equality on two pointers that are not in the same array defined behaviour?

請考慮一下

int main(void)
{
    int a;
    int b;
    int* pa = &a;
    int* pb = &b;

    int e = pa == pb;
}

這個定義明確嗎? papb不指向同一數組中的元素。

如果我可以引用標准: §6.5.9¶2關於==約束:

以下其中一項應持有:

  • 兩個操作數都有算術類型;
  • 兩個操作數都是指向兼容類型的限定或非限定版本的指針;
  • 一個操作數是指向對象類型的指針,另一個是指向合格或非限定版本的void的指針; 要么
  • 一個操作數是一個指針,另一個是空指針常量。

所以是的 - 你的代碼是完善的。 這是明確定義的 (為什么?因為標准沒有提到任何形式比較兩個不相關的指針是否相等是未定義的行為(所有訪問元素都不是。腳注-109))。 1

以下是§6.5.9¶6中的內容

兩個指針比較相等,當且僅當兩個都是空指針時,兩者都是指向同一對象的指針(包括指向對象的指針和開頭的子對象)或函數,兩者都是指向同一數組的最后一個元素的指針對象,或者一個是指向一個數組對象末尾的指針,另一個是指向不同數組對象的開頭的指針,該對象碰巧緊跟在地址空間中的第一個數組對象之后

1)鏈接部分(§6.5.9¶6)是描述使用==進行比較的兩個指針何時相等的部分。 根據法律,現在我們可以說所有其他案件都不相同。 沒有針對那些指定不明確的指控提出索賠。


為了澄清一點 - 關系運算符的規則與相等運算符的規則完全不同。 章節§6.5.8¶5 (關系運算符的語義)

比較兩個指針時,結果取決於指向的對象的地址空間中的相對位置。 .. 在所有其他情況下,行為未定義

明確提到這一點 - 即使是可比的 - 他們必須遵循上面指出的標准。 因此,在兩個不相關的指針上使用關系運算符將產生未定義的行為。


擴展討論:

還有一件事要澄清 - 約束語義是完全不同的東西。 如果是操作員的標准 - 它首先提供必須持有的約束,但它只是硬幣的一面。 語義怎么樣? 之后提到的標准。 現在,當最初回答時,這個答案集中在太多的約束而不是語義上。 為什么這很重要? 當我們研究關系運算符時,我們會知道。 檢查它的限制 -

以下其中一項應持有:

  • 兩個操作數都有實物類型; 要么
  • 兩個操作數都是指向兼容對象類型的限定或非限定版本的指針。

只有通過研究這個約束 - 可以說ptr < NULL是明確定義的。 嗯,它不是 - 而且從語義特別是從§6.5.8¶5開始就可以清楚地看到它。 但是肯定ptr < NULL很好地形成了,因為它依賴於對它施加的約束。

這種行為定義明確。

關於等式運算符的C標准的第6.5.9節( ==!= )說明如下:

2下列之一應持有:

  • 兩個操作數都有算術類型;
  • 兩個操作數都是指向兼容類型的限定或非限定版本的指針 ;
  • 一個操作數是指向對象類型的指針,另一個是指向void的限定或非限定版本的指針;或者
  • 一個操作數是一個指針,另一個是空指針常量。

...

5否則,至少有一個操作數是指針。 如果一個操作數是指針而另一個是空指針常量,則空指針常量將轉換為指針的類型。 如果一個操作數是指向對象類型的指針而另一個是指向void的限定或非限定版本的指針,則前者將轉換為后者的類型。

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

根據第2段,它不要求兩個指針指向同一個對象,只要類型是兼容的,或者它們中的至少一個是void *NULL 第6段隨后說明了比較平等的兩個指針意味着什么。

這與6.5.8節不同,后者涉及關系運算符( <><=>= ),它們不允許在不相關的對象之間進行比較,即使類型相同:

5 比較兩個指針時,結果取決於指向的對象的地址空間中的相對位置。 如果兩個指向對象類型的指針都指向同一個對象,或者兩個指針都指向同一個數組對象的最后一個元素,則它們相等。 如果指向的對象是同一聚合對象的成員,則指向稍后聲明的結構成員的指針比指向結構中先前聲明的成員的指針要大,指向具有較大下標值的數組元素的指針比指向同一數組的元素的指針要大。具有較低的下標值。
指向同一個union對象的成員的所有指針都比較相等。 如果表達式P指向數組對象的元素並且表達式Q指向同一數組對象的最后一個元素,則指針表達式Q + 1比P大。 在所有其他情況下,行為未定義

這里,它說明了如何比較指向同一數組對象內部的兩個指針,並且在所有其他情況下該行為未定義。 第6.5.9節沒有這樣的措辭。

在旁注中,給出以下內容:

char a[5], b[5];

如果a在內存中被b立即跟隨,則6.5.9p6可以允許a + 5 == b評估為真。

暫無
暫無

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

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