各務 さんが書きました:やはり3以上を入れるとダメですよね…。
いいえ、3は最初に提示されたコードで入れられていて、問題は発見されていません。よって、この環境では大丈夫かもしれません。
各務 さんが書きました:未定義とはどのへんでしょうか?
以下の引用は、
N3337(直リンク:
http://www.open-std.org/jtc1/sc22/wg21/ ... /n3337.pdf)からの引用です。
5.2.1 Subscripting さんが書きました:The expression E1[E2] is identical (by definition) to *((E1)+(E2))
5.7 Additive operators さんが書きました:4 For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the
first element of an array of length one with the type of the object as its element type.
5 When an expression that has integral type is added to or subtracted from a pointer, the result has the type
of the pointer operand. 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 integral 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. Moreover, if the expression P points to the last element of an array object,
the expression (P)+1 points one past the last element of the array object, and if the expression Q points
one past the last element of an array object, the expression (Q)-1 points to the last element of the array
object. 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.
いま、(&f.x)[2]という式を考えると、これは*((&f.x)+(2))と等価です。
f.xは配列ではないので、&f.xは要素数1の配列の先頭要素へのポインタとみなします。
(&f.x)+(2)は要素数1の配列の2番目(ただし先頭要素を0番目とする)の要素へのポインタになります。
しかし、要素数1の配列の最後の要素は0番目、最後の要素の1個次の要素は1番目なので、
「2番目の要素」はこの配列またはこの配列の最後の要素の1個次の要素の範囲に収まっていません。
よって、この計算結果のふるまいは未定義になります。