1
char** buffer{ /* some buffer */ };
char* ptr1{buffer[0]};
char* ptr2{buffer[10]};

assert(ptr1 < ptr2);

2 つのポインターが同じバッファー内の異なる場所を指している場合、それらを比較しても安全ですか?

比較して、ポインターの範囲が有効かどうかを知りたい: assert(rangeBeginPtr < rangeEndPtr).

4

3 に答える 3

4

ポインターを関係演算子 ( <><=および>=) と比較できますが、両方が同じ配列の要素を指している場合、またはその配列の 1 つ前の要素を指している場合に限ります。それ以外は、 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]));

同じ配列内の 2 つの要素を比較する場合は、同じ型でなければならないことを除いて、型は含まれません。2 つの変数がある場合、それらが同じ型であっても異なる配列char *を指している場合、それは未指定です。

于 2013-08-26T12:52:31.067 に答える
3

ポインターの順序は、配列オブジェクトでのみ決定でき、それらが非void. ただし、1 つの配列オブジェクト内では、比較は明確に定義されています。標準の関連する条項は、5.9 [expr.rel] パラグラフ 2 です。

[...] (ポインター変換後の) 同じ型のオブジェクトまたは関数へのポインターは、次のように定義された結果と比較できます。

  • 同じ型の2 つのポインターpおよびqが同じオブジェクトまたは関数を指している場合、または両方が同じ配列の末尾の 1 つ後ろを指している場合、または両方が null の場合、p<=qおよびp>=q両方が yieldtrueおよびp<qおよびp>q両方が yieldになりfalseます。
  • 同じ型の2 つのポインターpqが、同じオブジェクトのメンバーではない異なるオブジェクト、同じ配列の要素、または異なる関数を指している場合、またはそのうちの 1 つだけが null である場合、 、 、 、および の結果p<qp>qp<=q指定p>=qです。
  • 2 つのポインターが同じオブジェクトの非静的データ メンバー、またはそのようなメンバーのサブオブジェクトまたは配列要素を再帰的に指す場合、後で宣言されたメンバーへのポインターは、2 つのメンバーが同じアクセス制御 (条項 11) を持ち、かつクラスが共用体でない場合。
  • 2 つのポインタが異なるアクセス制御 (第 11 節) を持つ同じオブジェクトの非静的データ メンバを指している場合、結果は規定されていません。
  • 2 つのポインターが同じユニオン オブジェクトの非静的データ メンバーを指している場合、それらは等しいと比較されます (void*必要に応じて への変換後)。2 つのポインターが同じ配列の要素を指している場合、または配列の末尾を超えた 1 つの要素を指している場合、添字が大きい方のオブジェクトへのポインターが比較されます。
  • その他のポインター比較は指定されていません。
于 2013-08-26T12:59:11.220 に答える