The lvalues discussed in section 6.3.2.1 can never be elements of an array declared with register , so the question of what their addresses mean never arises.
In paragraph 3, using an array declared with register , except as an operand of sizeof , _Alignof or & has undefined behavior. But the only way to get an lvalue for an array element is to use the array differently from arr[0] .
Therefore, it can never happen (with a specific behavior) that the lvalue discussed in paragraph 2 denotes an element of an array that could be declared with a register storage class.
In this light, the bracketed comment “has never been accepted” is clear. It applies only to objects that are not elements of the array, and the only way to create an address for such an object is to apply & . 1 Taking an address means using & .
Regardless of whether the evaluation is arr[0] or arr + 2 or even just arr (as in arr; and not as a sizeof operand or something else), then accepting the address of an array element does not matter. This does not affect what 6.3.2.1 means 2.
Regarding your question about how an array can have a register storage class, note 121 (in section 6.7.1) says: “Thus, the only operators that can be applied to an array declared using the register of a storage class specifier are sizeof and _Alignof. " (Although this is legal, it does not seem useful, since you can use sizeof and _Alignof without using register , so including register in the declaration does not seem to provide any useful property.)
Footnote
1 The exception is that in paragraph 6.7.2.1 in paragraph 15 it is said that a pointer to a structure can be converted to a pointer to its first member, and in paragraph 16 it is indicated that a pointer to a union can be converted to a pointer to any of its members . However, this requires an indication of the pointer to the collection (structure or union), which means that the aggregate itself cannot have a register storage class, and members inside the aggregate cannot be declared a storage class.
source share