2013-08-26 68 views
1
char** buffer{ /* some buffer */ }; 
char* ptr1{buffer[0]}; 
char* ptr2{buffer[10]}; 

assert(ptr1 < ptr2); 

如果兩個指針指向同一個緩衝區中的不同位置,比較它們是否安全?比較相同類型的指針是否安全?

我想知道指針範圍是否通過比較有效:assert(rangeBeginPtr < rangeEndPtr)

回答

4

可以比較與關係運算符(<><=>=)指針,只要它們都指向相同的陣列,或一個過去的該數組的一個元素。根據C++ 11 5.9 Relational operators,任何其他都是未指定的行爲。因此,考慮到:

char xyzzy[10]; 
char plugh[10]; 

所有這些被指定爲正常工作:

assert(&(xyzzy[1]) < &(xyzzy[4])); 
assert(&(xyzzy[9]) < &(xyzzy[10])); // even though [10] isn't there. 

但這些都不是:

assert(&(xyzzy[1]) < &(xyzzy[15])); 
assert(&(xyzzy[9]) < &(plugh[3])); 

類型不進入它除了它具有如果您要比較同一個數組中的兩個元素,請使用相同的類型。如果您有兩個char *變量,那麼即使它們具有相同類型,如果它們指向不同的數組,它們也是未指定的。

+7

結果未指定,但行爲不是未定義的。簡而言之,任何其他的'a

+0

*此處的「比較」表示'>< > = <='中的一個。平等測試('!=''==')不受限於指向同一數組內的對象的指針。 – 2013-08-26 12:55:59

+2

R.Martinho的評論非常重要,而'a

3

您可以僅使用數組對象確定指針的順序,如果它們不是void。但是,在一個數組對象中,比較是明確定義的。在標準的有關條款是5.9 [expr.rel]段2:

[...]對象指針或相同類型的(指針轉換後)的功能,可以進行比較,用其結果定義爲如下:

  • 如果兩個指針p和相同類型的指向相同的對象或功能或兩者點一個過去的同一陣列的末端,的q或均爲空,則p<=qp>=q都得到truep<qp>q兩者都產生false
  • 如果相同類型的兩個指針pq指向不是同一對象或同一數組元素或不同函數的成員的不同對象,或者如果其中只有一個爲空,則結果爲p<qp>qp<=qp>=q是未指定的。
  • 如果兩個指針指向同一對象的非靜態數據成員,或者指向此類成員的子對象或數組元素,則遞歸地,指向稍後聲明的成員的指針會比較大,前提是兩個成員具有相同的訪問控制(條款11),並提供他們的班級不是工會。
  • 如果兩個指針指向具有不同訪問控制的同一對象的非靜態數據成員(第11章),則結果未指定。
  • 如果兩個指針指向同一個聯合對象的非靜態數據成員,則它們相等(如果需要,轉換爲void*後)。如果兩個指針指向相同數組的元素或超出數組末尾的元素,則指向具有較高下標的對象的指針相比較高。
  • 其他指針比較未指定。
2

==!=是有效的和用於同一類型的所有指針良好定義。 <,<=,>>=僅對指向同一數組中的對象或數組的一端的指針有意義。如果子對象具有相同的類型和相同的訪問說明符,則它們對於指向類對象的子對象的指針也是有意義的。如果這些條件未得到滿足,則結果不明確;一種直接後果是a<bb<c確實不是意味着a<c,因此您不能使用<等作爲排序函數的比較器。

std::less,std::less_equal,std::greaterstd::greater_equal對於指針類型都定義了總排序;他們可以用於分類。

+0

*>「一個直接的後果是a

+2

@VittorioRomeo - 不,該條款的條件是「如果這些條件不符合......」。 –

相關問題