Doc No: | SC22/WG14/N1397 |
---|---|
Date: | 2009-09-25 |
Reply to: | Clark Nelson <[email protected]> |
Arjun Bijanki <[email protected]> |
SC22/WG21/N2341 proposes wording to the C++ language and libraries to support alignment, and the language aspects of alignment in that paper are largely applicable to C. This paper proposes their adoption in a semantically equivalent manner (syntax aside, for the moment). The aspects of alignment intended primarily to support generic libraries in C++ are not included for adoption.
For reference, changes voted into the C++ working paper were:
alignas
) to declarationsalignof
expression to retrieve alignment requirements
of a type (like sizeof
for size)aligned_storage
,
aligned_union
)std::align
) for pointer alignment at
run timeSince the original adoption into C++, the alignas
specifier was
changed to the align
attribute.
Of those changes, the two proposed for C are the language facilities for specifying and querying alignment.
alignof
expression to retrieve alignment requirements
of a type (like sizeof
for size)The library changes are not proposed for C, since they're largely necessary for template containers and don't seem to have a high degree of utility for C code.
Facilities for packing and weaker alignment requirements are not proposed, mainly because packing presents issues (include code generation and ABI questions) above and beyond those of forcing greater alignment. If packing is considered essential, it should probably be specified using syntax different from that used for forcing greater alignment, and be made as a separate proposal.
An aligned memory allocation function is also included, based on posix_memalign
For purposes of the C standard, posix_memalign
has several problems,
roughly in order of decreasing severity (in my estimation):
errno
value, and the pointer to the newly-allocated
memory is passed back through a pointer argument.(void **)
,
which doesn't have the implicit convertibility of (void *)
. So
to use it in a strictly-conforming way would require the use of a variable of
type (void *)
, which is later assigned to a pointer of the appropriate
type.In my view, the first two reasons are sufficient motivation to change the interface; that effectively requires a change of name, which gives an opportunity to duck the last two problems as well. The proposed name of this function may be considered a place-holder.
The proposed wording draws heavily on the wording in WG21/N2341. Note: wording
additions are underlined; deletions are in strikethrough.
Add a new section following 6.2.7, with the following text:
1 Object types have alignment requirements which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type: stricter alignment can be requested using the
align
attribute.2 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)
.3 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. [Footnote: Every over-aligned type is or contains a struct or union type with a member to which an extended alignment has been applied.]4 Alignments are represented as values of the type
size_t
. Valid alignments include only those values returned by analignof
expression for fundamental types, plus an additional implementation-defined set of values, which may be empty. [Footnote: It is intended that every valid alignment value is an integral power of two]5 Alignments have an order from weaker to stronger or stricter alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.
6 The alignment requirement of a complete type can be queried using an
alignof
expression. The typeschar
,signed char
, andunsigned char
shall have the weakest alignment requirement.7 Comparing alignments is meaningful and provides the obvious results:
- Two alignments are equal when their numeric values are equal.
- Two alignments are different when their numeric values are not equal.
- When an alignment is larger than another it represents a stricter alignment.
Add alignof
to the list of keywords. (If a general attribute
proposal is accepted for C, it should not be necessary for align
to
be a reserved word, even though it appears to be one in the place-holder grammar
below.)
Modify the grammar as follows:
- unary-expression:
- postfix-expression
++
unary-expression--
unary-expression- unary-operator cast-expression
sizeof
unary-expressionsizeof (
type-name)
alignof (
type-name)
sizeof
alignof
operatorsModify paragraph 1 (Constraints) as follows:
1 The
sizeof
operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member. Thealignof
operator shall not be applied to a function type or incomplete type.
Add a new (Semantics) paragraph following p5:
The
alignof
operator yields the alignment requirement of its operand type. The result is an integer constant of typesize_t
. When applied to an array type, the result is the alignment of the element type.
It must be possible to add an alignment attribute to a declaration. Pending a general attribute proposal, this is presented as a simple option to make this possible:
- declaration-specifiers:
- storage-class-specifier declaration-specifiersopt
- type-specifier declaration-specifiersopt
- type-qualifier declaration-specifiersopt
- function-specifier declaration-specifiersopt
- alignment-attribute declaration-specifiersopt
Add a new section between 6.7.4 and 6.7.5, with the following text. The description of the syntax is a place-holder, pending a general attribute proposal.
Syntax
- 1 alignment-attribute:
[ [ align (
type-name) ] ]
[ [ align (
constant-expression) ] ]
Constraints
2 An alignment attribute shall not be specified in a declaration of a typedef, or a bit-field, or a function, or a parameter, or an object declared with the
register
storage-class specifier.3 The constant-expression shall be an integer constant expression. It shall evaluate to a valid fundamental alignment, or to a valid extended alignment supported by the implementation in the context in which it appears, or to zero.
4 The combined effect of all alignment attributes in a declaration shall not specify an alignment that is less strict than the alignment that would otherwise be required for the type of the object or field being declared.
Semantics
5 When the argument of the alignment attribute is a type-name, it is interpreted as
align ( alignof (
type-name) )
.6 The alignment requirement of the declared object or field is taken to be the specified alignment. An alignment attribute that specifies an alignment value of zero has no effect. When multiple alignment attributes are specified in a declaration, the effective alignment requirement is the strictest specified alignment.
7 If the defining declaration of an object has an alignment specifier, any non-defining declaration of that object shall either specify equivalent alignment or have no alignment specifier. If declarations of an object in different translation units have different alignment specifiers, the behavior is undefined.
<stddef.h>
Modify paragraph 2 as follows:
The types are
ptrdiff_twhich is the signed integer type of the result of subtracting two pointers;
size_twhich is the unsigned integer type of the result of the
sizeof
operator;andmax_align_t
which is an object type whose alignment is as great as is supported by the implementation in all contexts; and
wchar_twhich is an integer type whose range ....
Change paragraph 1 as follows:
The order and contiguity of storage allocated by successive calls to the
calloc
,malloc
,andrealloc
, andaligned_alloc
functions is unspecified. The pointer returned if the allocation succeeds is 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 (until the space is explicitly deallocated)....
free
functionModify paragraph 2 as follows:
... Otherwise, if the argument does not match a pointer earlier returned by
thea memory management function, ...calloc
,malloc
, orrealloc
realloc
functionModify paragraph 3 as follows:
... Otherwise, if ptr does not match a pointer earlier returned by
thea memory management function, ....calloc
,malloc
, orrealloc
aligned_alloc
functionAdd a new section following 7.20.3.4, with the following text:
Synopsis
1 #include <stdlib.h> void *aligned_alloc(size_t alignment, size_t size);Description
2 The
aligned_alloc
function allocates space for an object whose alignment is specified byalignment
, whose size is specified bysize
, and whose value is indeterminate. The value ofalignment
shall be a valid alignment supported by the implementation, and the value ofsize
shall be an integral multiple ofalignment
.Returns
3 The
aligned_alloc
function returns either a null pointer or a pointer to the allocated space.
Change the grammar of unary-expression as follows:
- (6.5.3) unary-expression:
- postfix-expression
++
unary-expression--
unary-expression- unary-operator cast-expression
sizeof
unary-expressionsizeof (
type-name)
alignof (
type-name)
The syntax of the alignment attribute will also need to be added to the syntax summary annex, but the details are not yet known.
<stddef.h>
Add the declaration of aligned_alloc
:
void *realloc(void *ptr, size_t size);
void *aligned_alloc(size_t alignment, size_t size);
void abort(void);
Add a new bullet with the following text:
- The set of extended alignment values supported, and the contexts in which they are supported (6.2.8).