0

This code is invalid:

int x = _Alignof(int[]);

Note: GCC produces:

error: invalid application of '__alignof__' to incomplete type 'int[]'

while Clang produces:

<nothing>

Per Semantics (emphasis added):

When applied to an array type, the result is the alignment requirement of the element type.

However, in order to yield the alignment requirement of the element type, the size is not needed.

Hence, will it be useful to make the code above valid by changing the constraint

from:

The _Alignof operator shall not be applied to a function type or an incomplete type.

to (emphasis added):

The _Alignof operator shall not be applied to a function type or an incomplete non-array type.

pmor
  • 5,392
  • 4
  • 17
  • 36

1 Answers1

1

C2x: if _Alignof(array type) yields the alignment of the element type, then will it be useful to permit _Alignof(incomplete array type)?

As you observe, the language spec explicitly forbids applying the _Alignof operator to an expression of incomplete type or to the parenthesized name of such a type. This is a language constraint, so it is a conformance requirement that implementations diagnose violations, and in this sense, Clang's behavior is non-conforming.

On the other hand, you're right that there is an opportunity for fully consistent _Alignof behavior when the type in question is an array type with complete element type but unspecified number of elements. The number of elements in an array is not a factor in its alignment requirement, so this operation could be resolved according to ordinary _Alignof semantics, provided only that the spec allowed it.

Would it be useful? I'm sure that depends on what range of possible uses one considers. I don't find _Alignof very useful in general, though it does have its moments. And since you can get the alignment of an array type directly from its element type, you don't need _Alignof for array types -- complete or not -- except in places where you don't know what type will be operated upon. That doesn't cut out all possible uses, but the window it leaves is small enough that I don't think it unreasonable for the spec to express the simpler constraint it does instead of the more complicated one that would be required to allow _Alignof on this one special class of incomplete types.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Thanks. Extra question: for `typedef char T[3]; _Alignas(8) T x;` does it mean that there is no standard way to query an alignment of `x` ? – pmor Mar 09 '22 at 00:44
  • @pmor, the `_Alignof` operator is the only standard way to explicitly evaluate alignment requirements, and it yields the alignment requirement of the type designated by the operand type name. In standard C, `_Alignof` (unlike `sizeof`) does not accept expressions, so there is no way to recognize that an object was declared with a stricter alignment requirement than that of its type. Not that I see how doing so would be useful, and I'm not even convinced that alignment of an object is unambiguously defined (as opposed to alignment *requirement* of a type). – John Bollinger Mar 09 '22 at 16:28
  • Re: "the simpler constraint". To remind: there are the similar "not xxx cases". Example: "A type has known constant size if the type is **not incomplete** and is **not a variable length array type**". Added as a result of [DR #312](http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_312.htm). – pmor Mar 30 '22 at 22:42
  • I'm not sure what you're trying to say, @pmor. Yes, that definition of "known constant size" was added in C11 to clarify the meaning of the term. How is that relevant here? – John Bollinger Mar 31 '22 at 14:55
  • The definition of "known constant size" contains "not xxx" phrases: "not incomplete", "not a variable length array type". My idea (see above) is to add "non-array". Hence, it should be OK, since the existing definitions (and maybe constraints too) already contain "not xxx / non-xxx" phrases. Example: "must be a non-null pointer". – pmor Mar 31 '22 at 18:17
  • @pmor, the complexity here is only partially a (human) language issue. It is also -- maybe more so -- a *semantic* issue. But I'm no apologist or gatekeeper for the standard. It's not me whom you need to persuade. – John Bollinger Mar 31 '22 at 18:47
  • Have a look: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1910.htm. – pmor Sep 02 '22 at 20:17
  • Ok, @pmor. And? FWIW, it does not look like that proposal had been adopted into C2x as of [a couple of months ago](https://www.open-std.org/jtc1/sc22/wg14/www/docs/N2912.pdf). And even if it were adopted at this relatively late date, that still would not provide a mechanism for detecting the overalignment you asked about -- not that between your first comment and now I have come up with any reason to think that doing so would be useful. – John Bollinger Sep 02 '22 at 20:43
  • 1) Re: "And?": FYI. 2) FYI: the last one is n3047 (August 4, 2022). 3) n1910 is only about "_Alignof(incomplete array type)", not about "_Alignof unary-expression". 4) FYI: in C++ [Querying the Alignment of an Object](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2152r1.pdf) has some nuances and edge cases. – pmor Sep 02 '22 at 21:17