2016-11-26 94 views
2

受此answering this question的啓發,我在C11和C99標準中挖掘了指針上等號運算符的使用(原始問題涉及關係運算符)。下面是C11不得不說(C99相似)在§6.5.9.6:指向不同對象的指針的平等比較

兩個指針比較平等的,當且僅當是空指針,都是指向同一個對象(包括對象指針和一個子對象在其開始處)或函數,它們都是指向同一數組對象的最後一個元素之後的指針,或者是指向一個指向一個數組對象末尾的指針的指針,另一個指向指向開始的指針不同的數組對象恰好緊隨地址空間中的第一個數組對象。 )

腳註94表示(並注意腳註是非標準的):因爲它們的相鄰構件更大的陣列中的相鄰的元件或

兩個對象可以是在存儲器中相鄰它們之間沒有填充的結構,或者因爲實現選擇將它們放置,所以即使它們不相關。如果先前的無效指針操作(例如訪問數組邊界外)產生未定義的行爲,後續比較也會產生未定義的行爲。

正文和非規範性說明似乎存在衝突。如果從文本正文中認爲'當且僅當'嚴重,那麼在除了那些規定的情況之外,沒有其他情況應該返回平等,並且UB沒有空間。所以,例如下面的代碼:

uintptr_t a = 1; 
uintptr_t b = 1; 
void *ap = (void *)a; 
void *bp = (void *)b; 
printf ("%d\n", ap <= bp); /* UB by §6.5.8.5 */ 
printf ("%d\n", ap < bp); /* UB by §6.5.8.5 */ 
printf ("%d\n", ap == bp); /* false by §6.5.9.6 ?? */ 

應打印等於零,apbp既不指向同一對象或函數,或任何列出其他位。

在§6.5.8.5(關係運算符)的行爲更加清晰(我的重點):

當兩個指針進行比較,結果依賴於對象的地址空間指向的相對位置至。如果指向對象或不完整類型的兩個指針都指向同一個對象,或者兩個指向同一個數組對象的最後一個元素,則它們相等。如果指向的對象是同一個聚合對象的成員,那麼稍後聲明的結構成員的指針比結構中較早聲明的成員的指針要多,指向具有較大下標值的數組元素的指針比指向同一數組元素的指針大具有較低的下標值。所有指向同一聯合對象成員的指針都相等。如果表達式P指向數組對象的元素,並且表達式Q指向相同數組對象的最後一個元素,則指針表達式Q+1的比較結果大於P在所有其他情況下,行爲未定義。

問題:

  • 我是正確的,有一些不確定性至於何時平等運營指針被允許UB(比較腳註和正文中)?

  • 如果沒有歧義,那麼在精確地將指針與等號運算符進行比較時應該是UB?例如,如果至少有一個指針是人爲創建的(每個以上),它總是UB嗎?如果一個指針指向的內存是free()d?鑑於腳註是非規範性的,可以得出結論:從來沒有UB,因爲所有'其他'比較必須產生false

  • §6.5.9.6是否真的意味着無意義但平等的指針的平等比較應該始終是錯誤的?

注意這個問題被標記爲;我不問在編譯器中做什麼,因爲我相信已經知道答案(用比較整數的技術來比較它們)。

+0

也許未定義行爲的表現之一就是有兩個指針比較平等,即使是平等的語義意義。未定義的行爲可以以複雜的方式與定義的行爲進行交互,而不會因此而被定義。 –

+0

@JohnColeman我同意,但根據我的閱讀,§6.5.9.6根本不允許UB。它堅持認爲比特平等但無意義的指針的平等比較應該是錯誤的。我編輯了這個問題,以使這一點更清晰。謝謝。 – abligh

+1

您可能是有歧義的。你引用的第一件事並沒有提及任何有關*有效*指針的比較,儘管這可能是意圖。好問題。 –

回答

0

我正確地指出什麼時候使用指針的相等運算符是UB時存在一些含糊之處?

沒有,因爲此通道從§6.5.9(3):

==!=運營類似於除了它們的優先級低的關係運算符。

意味着從§6.5.9下述(6)也適用於相等運算符:

當兩個指針進行了比較[...]在所有其他情況下,該行爲是未定義。

如果不存在歧義,何時可以將指針與等號運算符進行精確比較爲UB?

在標準沒有明確定義行爲的所有情況下都存在未定義的行爲。

如果至少有一個指針是人工創建的從任意整數轉換是否總是UB?

§6.3.2.3(5):

的整數可以被轉換爲任何指針類型。除了之前指定的以外,結果是實現定義的,可能沒有正確對齊,可能不指向引用類型的實體,並且可能是陷阱表示。

如果什麼人指針指向的內存已經free d?

第6.2.4節(2):

一個指針的值變爲不確定的當物體它指向到達其壽命的結束。

可以得出結論:從來沒有UB,所有'其他'比較必須產生錯誤嗎?

號的標準定義在什麼條件下必須對這兩個指針比較平等的,在什麼條件下必須對這兩個指針比較不相等。任何落在這兩組條件之外的兩個指針之間的任何相等比較都會調用未定義的行爲。

不§6.5.9(6)真的是毫無意義的,但按位等於指針的平等的比較應該始終是假的?

不,這是不確定的。

+0

downvoter會照顧評論嗎? – Oktalist