This issue has been automatically converted from the original issue lists and some formatting may not have been preserved.
Authors: WG 14, Joseph Myers
Date: 2013-07-23
Reference document: N1731
Submitted against: C11 / C17
Status: Fixed
Fixed in: C17
Converted from: n2396.htm
There are various deficiencies in the C11 text about alignment requirements.
Issue 2: Contexts in which alignments are supported
6.2.8#2 defines "fundamental alignment": "A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to _Alignof (max_align_t)."
6.2.8#3 defines "extended alignment": "An extended alignment is represented by an alignment greater than _Alignof (max_align_t). It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported. A type having an extended alignment requirement is an over-aligned type."
6.2.8#4 defines "valid alignment", saying "Alignments are represented as values of the type size_t. Valid alignments include only those values returned by an _Alignof expression for fundamental types, plus an additional implementation-defined set of values, which may be empty. Every valid alignment value shall be a nonnegative integral power of two.".
max_align_t is specified in 7.19#2 as "an object type whose alignment is as great as is supported by the implementation in all contexts".
The memory management functions in 7.22.3 are defined to return a pointer "suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated". In the case of aligned_alloc, there may be a stricter requirement given by the alignment passed to the function, but the alignment passed to the function can't result in memory any less-aligned than a fundamental alignment requirement. The alignment requirement still applies even if the size is too small for any object requiring the given alignment (see the response to C90 DR#075).
There are various problems with the above:
The term "fundamental type" is not defined in C11.
There is also no definition of what a "context" is in which an alignment might or might not be supported. In common implementation practice, separate contexts might be by the storage duration of the object (static, thread, automatic, allocated, with the last referring to the alignments guaranteed by calloc, malloc and realloc).
A "valid alignment" may not be a "fundamental alignment". Thus, whatever interpretation is adopted for "fundamental type", nothing in the standard requires the alignment of a "fundamental type" to be a "fundamental alignment". For example, say "long double" is a "fundamental type"; it would seem nonsensical if declaring "long double" objects (in any context) failed to work, but nothing seems to require malloc to return objects sufficiently aligned for long double.
Given these gaps in the definition, nothing in the normative text appears to imply footnote 57 "Every over-aligned type is, or contains, a structure or union type with a member to which an extended alignment has been applied.", although no doubt it reflects the intent.
If "fundamental type" is interpreted to mean "basic type", that is not sufficient to resolve these lacunae. For example, if
struct s { long double ld; }
has an alignment requirement bigger than long double, it should still be possible to allocate memory for it with malloc, and the same applies to any typedef from a standard header that might also have a bigger alignment requirement than any basic type.
The following principles seem natural for any fix for this issue:
Comment from WG14 on 2017-11-03:
Oct 2013 meeting
malloc
was required to return memory appropriate for "any type", and this should not be lost in the new wording regarding types that are not over-aligned. All other C99 behaviors must also be preserved as he describes as guidance.malloc
has been defined in terms of fundamental alignment, yet we do not anywhere strongly state that, say, int
has such fundamental alignment.Apr 2014 meeting
The author provided input to N1804 as a proposed technical corrigendum:
Change 6.2.8#2 to:
A fundamental alignment is a valid alignment less than or equal to
_Alignof (max_align_t)
. Fundamental alignments shall be supported by the implementation for objects of all storage durations. The alignment requirements of the following types shall be fundamental alignments:
- all atomic, qualified or unqualified basic types;
- all atomic, qualified or unqualified enumerated types;
- all atomic, qualified or unqualified pointer types;
- all array types whose element type has a fundamental alignment requirement;
- all types specified in clause 7 as complete object types;
- all structure or union types all of whose elements have types with fundamental alignment requirements and none of whose elements have an alignment specifier specifying an alignment that is not a fundamental alignment.
In 6.2.8#3, change "the contexts in" to "the storage durations of objects for which".
In 6.2.8#4, change "those values returned by an _Alignof expression for fundamental types" to "fundamental alignments".
(Note that the above admits the possibility that e.g. 1 and 4 are fundamental alignments, but 2 isn't, in which case it can't be an extended alignment either. If we want to ensure that 2 isn't a valid alignment at all in that case, rather than possibly having valid alignments that are neither fundamental nor extended, also change "additional implementation-defined set of values" to "additional implementation-defined set of extended alignments" in 6.2.8#4.) In 6.7.5#3, change "in the context in which it appears" to "for an object of the storage duration, if any, being declared". Add a new constraint at the end of 6.7.5#3: "An object shall not be declared with an over-aligned type with an extended alignment requirement not supported by the implementation for an object of that storage duration.".
(This deals with the point that if an over-aligned struct is defined, then objects with that type may be supported with some storage durations but not others, so it is the declaration of an object with that type that can violate a constraint rather than the declaration of the struct.)
In 7.19#2, change "whose alignment is as great as is supported by the implementation in all contexts" to "whose alignment is the greatest fundamental alignment".
(I'm trying to avoid an undesirable implication that if an alignment of e.g. 1MB is supported in all contexts - and it's quite plausible that an implementation can support more or less arbitrary alignments - then max_align_t must have such an alignment and so such an alignment must count as fundamental and so malloc must return memory suitable aligned for it.)
This is a difficult area and further study is required.
Oct 2014 meeting
The proposed changes have raised no concerns and so the committee has agreed to use them as the following Proposed Technical Corrigendum.
Change 6.2.8#2 to:
A fundamental alignment is a valid alignment less than or equal to
_Alignof (max_align_t)
. Fundamental alignments shall be supported by the implementation for objects of all storage durations. The alignment requirements of the following types shall be fundamental alignments:
- all atomic, qualified or unqualified basic types;
- all atomic, qualified or unqualified enumerated types;
- all atomic, qualified or unqualified pointer types;
- all array types whose element type has a fundamental alignment requirement;
- all types specified in clause 7 as complete object types;
- all structure or union types all of whose elements have types with fundamental alignment requirements and none of whose elements have an alignment specifier specifying an alignment that is not a fundamental alignment.
In 6.2.8#3, change
"the contexts in"
to
"the storage durations of objects for which".
In 6.2.8#4, change
"those values returned by an _Alignof expression for fundamental types"
to
"fundamental alignments".
In 6.7.5#3, change
"in the context in which it appears"
to
"for an object of the storage duration, if any, being declared".
Add a new constraint at the end of 6.7.5#3:
"An object shall not be declared with an over-aligned type with an extended alignment requirement not supported by the implementation for an object of that storage duration.".
In 7.19#2, change
"whose alignment is as great as is supported by the implementation in all contexts"
to
"whose alignment is the greatest fundamental alignment".