char** buffer{ /* some buffer */ };
char* ptr1{buffer[0]};
char* ptr2{buffer[10]};
assert(ptr1 < ptr2);
2 つのポインターが同じバッファー内の異なる場所を指している場合、それらを比較しても安全ですか?
比較して、ポインターの範囲が有効かどうかを知りたい: assert(rangeBeginPtr < rangeEndPtr)
.
char** buffer{ /* some buffer */ };
char* ptr1{buffer[0]};
char* ptr2{buffer[10]};
assert(ptr1 < ptr2);
2 つのポインターが同じバッファー内の異なる場所を指している場合、それらを比較しても安全ですか?
比較して、ポインターの範囲が有効かどうかを知りたい: assert(rangeBeginPtr < rangeEndPtr)
.
ポインターを関係演算子 ( <
、>
、<=
および>=
) と比較できますが、両方が同じ配列の要素を指している場合、またはその配列の 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 *
を指している場合、それは未指定です。
ポインターの順序は、配列オブジェクトでのみ決定でき、それらが非void
. ただし、1 つの配列オブジェクト内では、比較は明確に定義されています。標準の関連する条項は、5.9 [expr.rel] パラグラフ 2 です。
[...] (ポインター変換後の) 同じ型のオブジェクトまたは関数へのポインターは、次のように定義された結果と比較できます。
- 同じ型の2 つのポインター
p
およびq
が同じオブジェクトまたは関数を指している場合、または両方が同じ配列の末尾の 1 つ後ろを指している場合、または両方が null の場合、p<=q
およびp>=q
両方が yieldtrue
およびp<q
およびp>q
両方が yieldになりfalse
ます。- 同じ型の2 つのポインター
p
とq
が、同じオブジェクトのメンバーではない異なるオブジェクト、同じ配列の要素、または異なる関数を指している場合、またはそのうちの 1 つだけが null である場合、 、 、 、および の結果p<q
はp>q
未p<=q
指定p>=q
です。- 2 つのポインターが同じオブジェクトの非静的データ メンバー、またはそのようなメンバーのサブオブジェクトまたは配列要素を再帰的に指す場合、後で宣言されたメンバーへのポインターは、2 つのメンバーが同じアクセス制御 (条項 11) を持ち、かつクラスが共用体でない場合。
- 2 つのポインタが異なるアクセス制御 (第 11 節) を持つ同じオブジェクトの非静的データ メンバを指している場合、結果は規定されていません。
- 2 つのポインターが同じユニオン オブジェクトの非静的データ メンバーを指している場合、それらは等しいと比較されます (
void*
必要に応じて への変換後)。2 つのポインターが同じ配列の要素を指している場合、または配列の末尾を超えた 1 つの要素を指している場合、添字が大きい方のオブジェクトへのポインターが比較されます。- その他のポインター比較は指定されていません。