1. ホーム
  2. c++

CやC++はarray < array + SIZEを保証していますか?

2023-09-23 06:25:03

質問

配列があるとします。

int array[SIZE];

または

int *array = new(int[SIZE]);

CやC++は、以下のことを保証していますか? array < array + SIZE を保証していますか、また保証しているとしたらどこですか?

言語仕様に関わらず、多くのオペレーティングシステムでは、仮想アドレス空間の先頭をカーネル用に確保することで、この性質を保証していると理解しています。 私の質問は、これはまた 言語によって というよりも、大多数の実装によって保証されているのかということです。

例として、OS カーネルが低メモリで生活しており、時々 mmap の要求に応じて、ユーザー プロセスに最高ページの仮想メモリを提供することがあるとします。 もし malloc または ::operator new[] を直接呼び出す mmap を呼び出すと、配列の終端が仮想アドレス空間の先頭に接し、そのため array + SIZE がゼロになるような仮想アドレス空間の上部に配列の終端がある場合、これは言語の非準拠な実装に相当するのでしょうか?

明確化

なお、質問は ではなく について尋ねているのではありません。 array+(SIZE-1) を尋ねているのではありません。これは配列の最後の要素のアドレスです。 その1つは array . この問題は,ポインタ 配列の終端を過ぎたポインタ または、あるいは p+1 の場合 p が非配列オブジェクトへのポインタである場合 (選択された回答によって指された標準のセクションは、同じように扱われることを明確にしています)。

Stackoverflow は私に、なぜこの質問が この質問 . もう一つの質問は、ポインタの総順序付けをどのように実装するかというものです。 この質問は、本質的には、ライブラリはどのようにして std::less を実装し、異なる場所に配置されたオブジェクトへのポインタでも動作させることができるのか、ということです。

対照的に、私の質問は、配列の最後を過ぎたものが常に配列より大きいことが保証されているかどうかについてでした。 私の質問に対する答えがイエスであろうとノーであろうと、実際にあなたが std::less をどのように実装するかは変わらないので、他の質問は関係ないように思えます。 もし配列の終端を1つ過ぎたものと比較することが違法であるなら std::less はこの場合単に未定義の振る舞いを示すかもしれません。 (また、通常、標準ライブラリはコンパイラと同じ人々によって実装されるため、特定のコンパイラの特性を自由に利用することができます)。

どのように解決するのですか?

はい。セクションから 6.5.8 パラ5 .

式Pが配列オブジェクトの要素を指し、式Qが同じ配列オブジェクトの最後の要素を指す場合 を指し、式Qが同じ配列オブジェクトの最後の要素を指している場合 の最後の要素を指している場合、ポインタの式Q+1はPより大きく比較されます。

array はPであり、式 array + SIZE - 1 の最後の要素を指す。 array の最後の要素であるQを指します。 このように

array + SIZE = array + SIZE - 1 + 1 = Q + 1 > P = array