The address of an array has no pointer-to-array type
typedef float vec4[4]; typedef vec4 mat4[4];
mat4 a; int i4[4];
sizeof(*&a) /* pxx 4, gcc 64 */
sizeof(*(&i4)) /* pxx 4, gcc 16 */
(char *)(&a + 1) - (char *)&a /* pxx 1, gcc 64 */
(char *)(&i4 + 1) - (char *)&i4/* pxx 1, gcc 16 */
Measured 2026-09-27 with the pin v444 (sha256 92139531ef89) and with the build
that fixed regression-test-core-c-sizeof-ptr-to-array-field. Found while adding
parenthesised-deref rows to test/c_struct_member_of_array_typedef.c; the
sizeof(*(&a)) row was left out of that fixture because of this ticket.
The single reader for "what does this pointer value point at" is ir.inc
CPtrToArrShape; it has arms for symbols, m[i], pp[i], *pp and fields, but
none for an AN_ADDR of an array-typed operand. Adding that arm there would feed
IRPointerStride, the decayed-deref sizeof (CSizeofDecayedDeref) and the
subscript arm at once. Check the plain &a[0] and &s.arr spellings with it.
Resolution
Fixed 2026-09-27, wider than filed. &x + 1 stepped ONE BYTE for every C
operand, not only arrays (&i, &t, &s.f, &p), because IRPointerStride's
AN_ADDR arm kept Pascal's untyped-@ default. Now, in C:
&xof a whole array (a symbol or an array field) is a pointer to that array: a CPtrToArrShape arm (CAddrOfArrayShape), so*&adecays,(&a)[0][j]indexes a (the subscript arm indexes the array in place of the AN_ADDR base), and&a + 1steps the array.&m[1]of a decayed row keeps an AN_ADDR over the row (lowered as the row's value); the row builders stamp the dims they spent in ASTNDRowSubs and CRowShape gives it the row's shape.(*(&m[1]))[j][k]derefsrow + flat*elem.- Any other
&xsteps CObjectBytes(x): the size of the object an lvalue node designates (ir.inc), which also sizes a parenthesised row in sizeof (sizeof((m[0]))was 8, gcc 12). - The file-scope
int *q = &g[1][0];initializer built&g + byteOffsetand relied on the one-byte step; that add is now stamped pre-scaled. - A file-scope pointer-to-array initialised with anything but a bare name
(
int (*r)[3] = &g[1];,= g + 1) was skipped and stayed null; it is replayed at main like every other unfoldable pointer initializer.
gcc-diffed in test/c_address_of_an_array.c.