web-dev-qa-db-ja.com

ポインタpの場合、極端な場合、p <p + 1はfalseになる可能性がありますか?

ポインタ変数pの場合、p <(p + 1)がfalseである可能性はありますか?あなたの答えを説明してください。はいの場合、どのような状況でこれが発生する可能性がありますか?

P +1がオーバーフローして0に等しくなる可能性があるかどうか疑問に思いました。

C言語プログラム用のGCC-4.8を搭載した64ビットPCの場合:

int main(void) {
   void *p=(void *)0xFFFFFFFFFFFFFFFF;

   printf("p      :%p\n", p);
   printf("p+1    :%p\n", p+1);
   printf("Result :%d\n", p<p+1);
}

それは戻ります:

p      : 0xffffffffffffffff
p+1    : (nil)
Result : 0

ですから、この場合は可能だと思います。無効なポインタ位置の場合、それが発生する可能性があります。これが私が考えることができる唯一の解決策です。他にありますか?

注:仮定は行われません。これが発生する可能性があるかどうかにかかわらず、コンパイラ/プラットフォーム/アーキテクチャ/ OSを検討してください。

47
akarapatis

ポインタ変数pの場合、p<(p+1)がfalseである可能性はありますか?

pが正しいタイプの有効なオブジェクト(つまり、C++オブジェクトモデルに従って作成されたオブジェクト)を指している場合、いいえ。 p+1は、そのオブジェクトの後のメモリ位置を指し、常にpより大きく比較されます。

それ以外の場合、算術演算と比較の両方の動作が定義されていないため、結果がtrue、false、または黄色になります。

はいの場合、どのような状況でこれが発生する可能性がありますか?

それは起こるかもしれないし、起こらないかもしれない

p = reinterpret_cast<char*>(numeric_limits<uintptr_t>::max);

ポインタ演算が符号なし整数演算のように機能する場合、これにより、p+1の値がゼロになり、比較がp未満になるような数値オーバーフローが発生する可能性があります。またはそれは何か他のことをするかもしれません。

44
Mike Seymour

DOSでプログラミングしていて、 farポインタ (セグメントとオフセットで構成されるもの)があり、セグメントの最後のアドレスを指している場合はどうなりますか?それに1を追加します、およびポインタ ラップアラウンド ?それらを比較しているときは、ポインターを正規化するように見えるので、2番目のポインターp+1pよりも小さくなります。

これは暗闇の中での刺し傷ですが、テストに便利なDOSCコンパイラはありません。

14
dsolimano

無効なポインタで発生する可能性があります。

しかし、ポインタが有効なメモリ位置を指している場合、多くのオペレーティングシステム(Linuxなど)では、実際には発生しません(少なくともsizeof(*p)は大きすぎません)、なぜなら実際にはアドレス空間の最初と最後のページはマップされないからです(ただし、マッピングを強制することはできます) mmapMAP_FIXED)を使用します。

独立した実装(つまり、カーネル内、または一部のマイクロコントローラー)の場​​合、状況は異なり、実装固有です(おそらく 未定義の動作) 、または 不特定の動作 )。

10

非常に単純です。未定義の動作が含まれていない場合は発生しません。未定義の動作が存在する場合、非常に簡単に発生する可能性があります。詳細については、C標準またはC++標準のコピーをお読みください。

その結果、適合コンパイラは<演算子をまったく評価せず、代わりに1またはtrueを結果として使用できます。同じことが符号付き整数を使用した算術にも当てはまります(ただし、完全に合法的なコードがx> x + 1になる可能性がある符号なし整数には当てはまりません)。

サンプルコードはCまたはC++でもないため、標準に準拠したCまたはC++コンパイラではないモードでコンパイラを使用したようです。

10
gnasher729

Cでのポインタ比較。符号付きか符号なしか? スタックオーバーフロー:

C/C++では任意のポインタを合法的に比較することはできません。そのような比較の結果は定義されていません。

3
HappyCactus