ISO/IEC JTC1 SC22 WG14 N1507 - 2010-08-18
ISO/IEC JTC1 SC22 WG21 N3124 = 10-0114 - 2010-08-18
Lawrence Crowl (crowl@google.com, Lawrence@Crowl.org)
Daveed Vandevoorde (daveed@edg.com)
This paper revises
ISO/IEC JTC1 SC22 WG14 N1447 - 2010-03-22
ISO/IEC JTC1 SC22 WG21 N3093 = 10-0083 - 2010-03-22
The revision incorporates C++ core language subcommittee changes that make the alignment-specifier occupy the syntactic position of an attribute rather than a decl-specifier. This change has no effect on C compatibility. The revision also incorporates 'pack expansions' inadvertantly dropped in the reversion to pre-attribute syntax. This change has no effect on C compatibility.
Introduction
Fundamental Alignment
Alignof Operator
Declaring Alignment
Alignment Semantics
Aligned Allocation
Proposed Wording for C
4. Conformance
6.2.8 Alignment of objects
6.4.1 Keywords
6.7.5 Alignment specifier
7.1.2 Standard headers
7.new Alignment <stdalign.h>
A.1.2 Keywords
A.2.2 Declarations
B.new Alignment <stdalign.h>
Proposed Wording for C++
1.1 Scope [intro.scope]
2.12 Keywords [lex.key]
3.2 One definition rule [basic.def.odr]
3.11 Alignment [basic.align]
7.6.1 Attribute syntax and semantics [dcl.attr.grammar]
7.6.2 Alignment attribute specifier [dcl.align]
17.6.1.2 Headers [headers]
18.1 General [support.general]
18.10 Other runtime support [support.runtime]
20.7.6.6 Other transformations [meta.trans.other]
D.5 C standard library headers [depr.c.headers]
The compatibility between the C and C++ alignment facilities is important to many members of the respective communities. This paper analyses the compatibility between the draft standards, WG14 N1425. and N3035, WG21 N3035. with respect to alignment.
This document presents what we believe to be the consensus proposal of the C and C++ compatibility mailing list. It incorporates detailed proposed wording for both standards.
Both languages have the same notion of
fundamental alignment (<= alignof(max_align_t)
) and
extended alignment (> alignof(max_align_t)
).
Extended alignment support is implementation-defined in both languages.
Both languages intend to constrain the alignments to powers of two, but the wording to do so is confusing, and likely subject to misinterpretation. In particular, the 'weaker' constraint does not seem to be satisfiable unless the alignments are restricted to powers of two. Explicitly restricting alignment to powers of two would improve both languages.
Explicitly constrain alignments to powers of two.
Both C and C++ define an alignof
operator.
These have compatible syntax and semantics:
alignof (
type-name/id )
Neither language provides an alignof
rule for expressions.
alignof
unary-expression
In both languages, the result is of type size_t
,
and the results are meaningfully comparable.
It is in the declaration of alignment that C and C++ differ significantly.
C adds alignment-specifiers to its grammar.
_Align (
type-name )
_Align (
constant-expression )
The original C++ proposal did essentially the same, but with a different keyword.
alignas (
type-id )
alignas (
constant-expression )
However, the current C++ working draft uses attributes.
;
where the alignment attribute is one of:
align (
type-name )
align (
assignment-expression )
and where the assignment-expression shall be an integral constant expression.
Spell the C1x keyword as "_Alignas
",
and revert the C++ proposal to a keyword,
but syntactically in the position of attributes.
alignas (
type-id )
...
optalignas (
constant-expression )
...
opt
Introduce a system header, <stdalign.h>
,
analagous to <stdbool.h>
,
that creates an identical spelling in both C and C++ for the keyword.
Example:
#ifndef __cplusplus
#define alignas _Alignas
#define __alignas_is_defined 1
#endif
Fortunately, C and C++ have very similar semantics for the effect of declaring alignment.
Type alignment, make_align(
type)
,
is defined as make_align(alignof(
type))
.
Alignment to zero has no effect.
When multiple alignments are specified, the strictest takes effect.
It is unclear what happens when there are multiple alignments and one is zero. Does that one alignment have no effect, or is there no effect on the declaration?
If different translation units have different alignments, the behavior is undefined.
However, there are some differences.
Both C and C++ explicitly disallow alignment to less than the natural alignment. This facility is useful for accessing legacy binary files. However, relaxed alignments on pointers cause serious implementation problems for garbage-collected C++0x implementations. One potential compromise is to allow it for integers, but not for pointers.
C requires subsequent declarations to have the same or no alignment. C++ requires the non-defining declarations to have the same or no alignment. Always specifying alignment would be compatible in both languages, but not doing so only sometimes.
Define each individual alignment to zero to have no effect. That is, when there are multiple alignments specified, only alignments to zero have no effect.
A portable program cannot make use of relaxed alignment, so we propose that it remains disallowed in C and in C++.
Require that a definition or a tentative definition specifies the alignment; other declarations shall have the same alignment or no alignment.
C defines an aligned_alloc
function.
C++ appears to add nothing for aligned allocation,
though does leave some support implementation-defined.
Update the C++ working draft section 1.2 [intro.refs] to refer to the 2011 C standard. This date may need to change.
These edits are relative to working draft WG14 N1425.
Add <stdalign.h>
to the list of headers for freestanding implementations
in paragraph 6.
Add <stdalign.h>
to the list of forward references.
Edit paragraph 1 as follows.
Object types have alignment requirements which place restrictions on the addresses at which objects 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
_Alignas
keyword.
Edit paragraph 3 as follows.
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: It is intended that every valid alignment value is an integral power of two. —end footnote]Every alignment value shall be an integral power of two.
In paragraph 1,
change _Align
to _Alignas
.
In paragraph 1,
change _Align
to _Alignas
.
In paragraph 5,
change _Align
to _Alignas
.
Edit paragraph 6 as follows.
The alignment requirement of the declared object or field is taken to be the specified alignment. An alignment specification of zero has no effect. [Footnote: An alignment specification of zero also does not affect other aligment specifications in the same declaration. —end footnote:] When multiple alignment specifiers occur in a declaration, the effective alignment requirement is the strictest specified alignment.
Edit paragraph 7 as follows.
If the definition of an object has an alignment specifier, any other declaration of that object shall either specify equivalent alignment or have no alignment specifier. If the definition of an object does not have an alignment specifier, any other declaration of that object shall have no alignment specifier. If declarations of an object in different translation units have different alignment specifiers, the behavior is undefined.
Add <stdalign.h>
to the list of standard headers
in paragraph 2.
<stdalign.h>
Add a new section after
"7.17 Boolean type and values <stdbool.h>
.
Add a new paragraph 1 as follows.
The header
<stdalign.h>
defines two macros.
Add a new paragraph 2 as follows.
The macro
alignas
expands to
_Alignas
.
Add a new paragraph 3 as follows.
The remaining macro is suitable for use in
#if
preprocessing directives. It is
__alignas_is_defined
which expands to the integer constant 1.
In paragraph (6.4.1),
change _Align
to _Alignas
.
In paragraph (6.7.5),
change _Align
to _Alignas
.
<stdalign.h>
Add a new section as follows.
alignas
__alignas_is_defined
These edits are relative to working draft WG21 N3092. They assume that the resolution of Core issue 972 agreed on in Rapperswill will go into the working paper. (That resolution makes it possible to specify a sequence of attribute-specifiers, and therefore a sequence of alignas constructs.)
Edit paragraph 2 as follows. Note that this edit may need to be delayed until the C standard appears.
C++ is a general purpose programming language based on the C programming language as described in ISO/IEC 9899:
19992011 Programming languages — C (hereinafter referred to as the C standard ). In addition to the facilities provided by C, C++ provides additional data types, classes, templates, exceptions, name spaces, inline functions, operator overloading, function name overloading, references, free store management operators, and additional library facilities.
Add the keyword alignas
before the keyword alignof
.
Edit paragraph 1 as follows. Note the inserted comma.
Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addressses at which an object of that type may be allocated. An aligment 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 alignment attribute (7.6.2)alignment specifier ([dcl.align]).
Edit paragraph 4 as follows.
Alignments are represented as values of the type
std::size_t
. Valid alignments include only those values returned by analignof
expression for the fundamental types plus an additional implementation-defined set of values, which may be empty.[Footnote: It is intended that every valid alignment value be an integral power of two. —end footnote]Every alignment value shall be an integral power of two.
Within paragraph 1, edit as follows:
- attribute-specifier:
[ [
attribute-list] ]
- alignment-specifier
- alignment-specifier:
alignas (
type-id) ...
optalignas (
alignment-expression) ...
opt
Edit the section heading as above.
Edit paragraph 1 as follows.
The attribute-tokenalign
specifies alignment (3.11). The attribute shall have one of the following forms:
align (
type-id)
align (
assignment-expression)
The attribute may be followed by an ellipsis.The attributeAn alignment-specifier may be applied to a variable that is neither a function parameter nor declared with theregisterregister
storage class specifier and to a class data member that is not a bit-field.The attributeAn alignment-specifier may also be applied to the declaration of a class or enumeration type. An alignment-specifier followed by an ellipsis is a pack expansion ([temp.variadic]).
Edit within paragraph 2 as follows.
When the
alignment attributealignment-specifier is of the formalignas (
assignment-expression)
:
Edit paragraph 3 as follows.
When the
alignment attributealignment-specifier is of the formalignas(
type-id)
, it shall have the same effect asalignas(alignof(
type-id))
([expr.alignof]).
Edit paragraph 4 as follows.
When multiple
alignment attributesalignment-specifiers are specified for an object, the alignment requirement shall be set to the strictest specified alignment.
Edit paragraph 5 as follows.
The combined effect of all
alignment attributesalignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would otherwise be required for the object being declared.
Edit paragraph 6 as follows.
If the defining declaration of an entity has an
alignment attributealignment-specifier, any non-defining declaration of that entity shall either specify equivalent alignment or have noalignment attributealignment-specifier. Conversely, if any declaration of an entity has analignment attributealignment-specifier, every defining declaration of that entity shall specify an equivalent alignment. No diagnostic is required if declarations of an entity have differentalignment attributealignment-specifier in different translation units.[Example:
// Translation unit #1: struct S { int x; } s, p = &s; // Translation unit #2:
struct [[align(16)]] S; // error: definition of S lacks alignment; nostruct alignas(16) S; // error: definition of S lacks alignment; no extern S* p; // diagnostic required—end example]
Edit paragraph 7 as follows.
[Example: An aligned buffer with an alignment requirement of
A
and holdingN
elements of typeT
other thanchar
,signed char
, orunsigned char
can be declared as:
T buffer [[ align(T), align(A) ]] [N];alignas(T) alignas(A) T buffer[N];Specifying
align(T)
in the attribute-listalignas(T)
ensures that the final requested alignment will not be weaker thanalignof(T)
, and therefore the program will not be ill-formed. —end example]
Edit paragraph 8 as follows.
[Example:
void f [[ align(double) ]] (); // error: alignment applied to functionalignas(double) void f(); // error: alignment applied to functionunsigned char c [[ align(double) ]] [sizeof(double)];alignas(double) unsigned char c[sizeof(double)]; // array of characters, suitably aligned for a double extern unsigned char c[sizeof(double)]; // no alignas necessaryextern unsigned char c [[ align(float) ]] [sizeof(double)];alignas(float) extern unsigned char c[sizeof(double)]; // error: different alignment in declaration—end example]
Add <cstdalign>
to "Table 14 — C++ headers for C library facilities".
Add <cstdalign>
to "Table 16 — Language support library summary"
under "18.10 Other runtime support".
Add a new table after
"Table 26 — Header <cstdbool>
synopsis".
Table ?? — Header <cstdalign>
synopsis".Type Names(s) Macro: __alignas_is_defined
Add a new paragraph after paragraph 6.
The header
<cstdalign>
and the header<stdalign.h>
shall not define a macro namedalignas
.
Edit within table 53 as follows.
Template | Condition | Comments |
---|---|---|
template < std::size_t Len,
std::size_t Align = default-alignment>
struct aligned_storage;
|
Len shall not be zero.
Align shall be equal to alignof<T>
for some type T or to default-alignment.
|
The value of default-alignment
shall be the most stringent alignment requirement for any C++ object type
whose size is no greater than Len (3.9).
The member typedef type
shall be a POD type
suitable for use as uninitialized storage for any object
whose size is at most Len
and whose alignment is a divisor of Align .
|
template < std::size_t Len, class ... Types >
struct aligned_union;
|
At least one type is provided. |
The member typedef type
shall be a POD type
suitable for use as uninitialized storage for any object
whose type is listed in Types ;
its size shall be at least Len .
The static member alignment_value
shall be an integral constant of type std::size_t
whose value is the strictest alignment of all types
listed in Types .
|
... | ... | ... |
Edit paragraph 1 as follows.
[Note: A typical implementation would define aligned_storage as:
template <std::size_t Len, std::size_t Alignment> struct aligned_storage { typedef struct {
unsigned char __data [[ align(Alignment) ]] [Len];alignas(Alignment) unsigned char __data[Len]; } type; };—end note]
Add <stdalign.h>
to "Table 144 — C headers".