多くの例で、次のように書かれているのを見ました。
#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 から:
単項
&
演算子はそのオペランドのアドレスを生成します... オペランドが演算子の結果である場合、演算[]
子もによって暗示される&
単項も評価されず、結果は演算子が削除され、演算子がに変更されたかのようになります。オペレーター。*
[]
&
[]
+