多くの例で、次のように書かれているのを見ました。
#define N 5
....
int a[N], *p;
....
for (p = &a[0]; p < &a[N]; p++);
存在しないことは明らかですa[N]が、コンパイラが警告(範囲外など)やエラーを出さないのはなぜですか、またはUBを呼び出すのですか?
多くの例で、次のように書かれているのを見ました。
#define N 5
....
int a[N], *p;
....
for (p = &a[0]; p < &a[N]; p++);
存在しないことは明らかですa[N]が、コンパイラが警告(範囲外など)やエラーを出さないのはなぜですか、またはUBを呼び出すのですか?
のメモリ&a[N]はプログラムからアクセスされることはないので、問題ありません。C 標準では、配列オブジェクト内または配列オブジェクトの末尾の 1 つ後ろのポインターを比較できます。
以下の議論に関する編集:
&a[N]は未定義の動作を引き起こしません。これは とまったく同じa + Nです。C 標準、6.5.3.2 アドレスおよび間接演算子、段落 3 から:
単項
&演算子はそのオペランドのアドレスを生成します... オペランドが演算子の結果である場合、演算[]子もによって暗示される&単項も評価されず、結果は演算子が削除され、演算子がに変更されたかのようになります。オペレーター。*[]&[]+