6
votes

C 2011 (draft N1570) 6.3.2.1 3 says:

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

C 2018 6.3.2.1 3 says:

Except when it is the operand of the sizeof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

Why is _Alignof missing from the latter?

C 2018 Foreward 7 says:

There are no major changes in this edition, only technical corrections and clarifications.

This implies there was something incorrect about exempting _Alignof from the array conversion rule, causing it to be removed. However, it should be possible to apply _Alignof to arrays, as C 2018 6.5.3.4 3 says:

The _Alignof operator yields the alignment requirement of its operand type. The operand is not evaluated and the result is an integer constant. When applied to an array type, the result is the alignment requirement of the element type.

1
That is a very good question to an issue I encountered by accident. - IMHO The committee should provide an addendum to clarify at least with a few words all of the made changes at any new standard release.RobertS supports Monica Cellio

1 Answers

10
votes

In both the C11 and C18 Standards, the _Alignof operator may have a type name as an operand, but not an expression. From §6.5.3 of the C11 Draft Standard:

Syntax

      unary-expression:
             postfix-expression
             ++ unary-expression
             -- unary-expression
             unary-operator cast-expression
             sizeof unary-expression
             sizeof ( type-name )
             _Alignof ( type-name )
      unary-operator: one of
             & * + - ~ !

The sizeof operator may have either an expression or a parenthesized type name as an operand, but since it is a constraint violation to use anything other than a parenthesized type name as the argument to _Alignof, there is simply no need for the special exception for array conversions here.


It turns out that the change was made between the release of the N1570 Draft Standard and the final release of the C11 Standard (ISO/IEC 9899:2011). There is some discussion in this SO answer, which references discussion in this Google Groups thread in which Larry Jones of the ISO C Committee suggests that:

The biggest change was removing _Alignof from a bunch of places it shouldn't have been added (based on the erroneous notion that it takes either a type or an expression like sizeof does when it really only takes a type): 6.3.2.1p2, p3, p4, fn. 65; and 6.7.1 fn. 121.