ポインタ演算

http://alohakun.blog7.fc2.com/blog-entry-931.html

  char (*p9)[10] = (char (*) [10])&"0123456789abcdefghi";
  puts(*p9);
  printf("%d\n", sizeof(*p9));
  p9++; // 10 バイト進む
  puts(*p9);

最後の例の意味がちゃんとわかれば,ポインタを理解できていると思って良いかもしれません.

このコードの「意味」が本当に存在する(仕様で動作が定義されている)のか、ちゃんとわからなかった:-)ので少し考えてみました。

  • まず、structではなく配列なので、sizeof(*p9)や、p9++の増分が、10バイトではなく12バイトとか16バイトだったり、みたいなpaddingの心配はありません。
  • どちらもcharの配列なので、aliasルールには抵触しません。
  • 最大の問題はISO規格6.5.6.8の記述。ポインタと整数の加算の定義なのですが、

If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. (中略) If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. (強調筆者)

この文章が曖昧で、どっちなのかわかりません…。厳密に解釈すると未定義動作?