Doc No: SC22/WG14/N1397
Date: 2009-09-25
Reply to: Clark Nelson <[email protected]>
Arjun Bijanki <[email protected]>

Adding Alignment Support to C

Summary

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:

Since 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.

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):

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.

Wording

The proposed wording draws heavily on the wording in WG21/N2341. Note: wording additions are underlined; deletions are in strikethrough.

6.2.8 Alignment of objects

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 an alignof 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 types char, signed char, and unsigned char shall have the weakest alignment requirement.

7 Comparing alignments is meaningful and provides the obvious results:

6.4.1 Keywords

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.)

6.5.3 Unary operators

Modify the grammar as follows:

unary-expression:
postfix-expression
++ unary-expression
-- unary-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )
alignof ( type-name )

6.5.3.4 The sizeof operator and alignof operators

Modify 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. The alignof 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 type size_t. When applied to an array type, the result is the alignment of the element type.

6.7 Declarations

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

6.7.4a Alignment specifiers

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.

7.17 Common definitions <stddef.h>

Modify paragraph 2 as follows:

The types are

	ptrdiff_t

which is the signed integer type of the result of subtracting two pointers;

	size_t

which is the unsigned integer type of the result of the sizeof operator; and

	max_align_t

which is an object type whose alignment is as great as is supported by the implementation in all contexts; and

	wchar_t

which is an integer type whose range ....

7.20.3 Memory management functions

Change paragraph 1 as follows:

The order and contiguity of storage allocated by successive calls to the calloc, malloc, and realloc , and aligned_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)....

7.20.3.2 The free function

Modify paragraph 2 as follows:

... Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc a memory management function, ...

7.20.3.4 The realloc function

Modify paragraph 3 as follows:

... Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc a memory management function, ....

7.20.3.5 The aligned_alloc function

Add 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 by alignment, whose size is specified by size, and whose value is indeterminate. The value of alignment shall be a valid alignment supported by the implementation, and the value of size shall be an integral multiple of alignment.

Returns

3 The aligned_alloc function returns either a null pointer or a pointer to the allocated space.

A.2.1 Expressions

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-expression
sizeof ( 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.

B.19 General utilities <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);

J.3.13 Architecture

Add a new bullet with the following text: