POD 结构或标准布局类型的成员是否保证根据其对齐要求对齐?
Are members of a POD-struct or standard layout type guaranteed to be aligned according to their alignment requirements?
给定一个 POD 结构(在 C++03 中)或一个标准布局类型(在 C++11 中),所有成员都有基本的对齐要求,是否保证每个成员都对齐根据其对齐要求?
换句话说,对于标准布局类型 S
、
中 { m0
... mn
} 中的所有成员 m_k
struct S {
T0 m0;
T1 m1;
...
TN mn;
};
是否保证以下表达式的计算结果为 true
?
(offsetof(S,m_k) % alignof(decltype(S::m_k))) == 0
请给出C++03和C++11的答案并引用标准的相关部分。来自 C 标准的支持证据也会有所帮助。
我对 C++03 标准 (ISO/IEC 14882:2003(E)) 的解读是,它对 POD 结构中成员的对齐保持沉默,除了第一个成员.相关段落为:
在规范的语言中,对象是"region of storage":
1.8 The C + + object model [intro.object]
1.8/1 The constructs in a C + + program create, destroy, refer to, access, and manipulate objects. An object is a region of storage. ...
对象根据对齐要求分配:
3.9 Types [basic.types]
3.9/5 Object types have alignment requirements (3.9.1, 3.9.2). The alignment of a complete object type is an implementation-defined integer value representing a number of bytes; an object is allocated at an address that meets the alignment requirements of its object type.
基本类型有对齐要求:
3.9.1 Fundamental types [basic.fundamental]
3.9.1/3 For each of the signed integer types, there exists a corresponding (but different) unsigned integer type: "unsigned char", "unsigned short int", "unsigned int", and "unsigned long int," each of which occupies the same amount of storage and has the same alignment requirements (3.9) as the corresponding signed integer type;...
填充 可能 由于 "implementation alignment requirements":
9.2 Class members [class.mem]
9.2/12 Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic
data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
9.2/12中的"allocated"和3.9/5中的"allocated"是同一个意思吗?规范中 "allocated" 的大多数使用是指动态存储分配,而不是结构内部布局。在 9.2/12 中使用 may 似乎暗示 3.9/5 和 3.9.1/3 的对齐要求可能并不严格要求结构成员。
POD 结构的第一个成员将根据结构的对齐要求进行对齐:
9.2/17 A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment. ]
[在以上所有引号中添加了强调。]
POD结构的每个元素本身就是一个对象,只能根据这些对象的对齐要求分配对象。但是,对齐要求可能会发生变化,因为某些东西是另一个对象的子对象 ([basic.align]/1, 2:
1 Object types have alignment requirements (3.9.1, 3.9.2) 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 alignment specifier (7.6.2).
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(std::max_align_t)
(18.2). The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject. [Example:
struct B { long double d; };
struct D : virtual B { char c; }
When D
is the type of a complete object, it will have a subobject of type B
, so it must be aligned appropriately for a long double
. If D
appears as a subobject of another object that also has B
as a virtual base class, the
B
subobject might be part of a different subobject, reducing the alignment requirements on the D
subobject.—end example ] The result of the alignof
operator reflects the alignment requirement of the type in the
complete-object case.
[强调已添加]
虽然示例通过继承引用子对象,但规范的措辞只是泛指子对象,所以我相信同样的规则适用,所以一方面你可以 假设每个子对象都对齐以便可以访问。另一方面,不,你 不能 必然假设这与 alignof
给你的对齐方式相同。
[参考来自N4296,但我相信这同样适用于所有最新版本。当然,C++98/03 根本没有 alignof
,但我相信同样的基本原则适用——成员将对齐以便可以使用,但对齐要求不一定与将它们用作独立对象时相同。]
每种类型都有两个不同的对齐要求。一个对应于完整的对象,另一个对应于子对象。 [basic.align]/2:
The alignment required for a type might be different when it is used
as the type of a complete object and when it is used as the type of a
subobject. [ Example:
struct B { long double d; };
struct D : virtual B { char c; };
When D
is the type of a complete object, it will have a subobject of
type B
, so it must be aligned appropriately for a long double
. If
D
appears as a subobject of another object that also has B as a
virtual base class, the B
subobject might be part of a different
subobject, reducing the alignment requirements on the D
subobject.
—end example ] The result of the alignof
operator reflects the alignment requirement of the type in the complete-object case.
我想不出成员子对象的任何具体示例 - 但肯定有 none! -,但上面的段落承认了成员子对象的对齐方式比 alignof
更弱的可能性,这将使您的条件失败。
给定一个 POD 结构(在 C++03 中)或一个标准布局类型(在 C++11 中),所有成员都有基本的对齐要求,是否保证每个成员都对齐根据其对齐要求?
换句话说,对于标准布局类型 S
、
m0
... mn
} 中的所有成员 m_k
struct S {
T0 m0;
T1 m1;
...
TN mn;
};
是否保证以下表达式的计算结果为 true
?
(offsetof(S,m_k) % alignof(decltype(S::m_k))) == 0
请给出C++03和C++11的答案并引用标准的相关部分。来自 C 标准的支持证据也会有所帮助。
我对 C++03 标准 (ISO/IEC 14882:2003(E)) 的解读是,它对 POD 结构中成员的对齐保持沉默,除了第一个成员.相关段落为:
在规范的语言中,对象是"region of storage":
1.8 The C + + object model [intro.object]
1.8/1 The constructs in a C + + program create, destroy, refer to, access, and manipulate objects. An object is a region of storage. ...
对象根据对齐要求分配:
3.9 Types [basic.types]
3.9/5 Object types have alignment requirements (3.9.1, 3.9.2). The alignment of a complete object type is an implementation-defined integer value representing a number of bytes; an object is allocated at an address that meets the alignment requirements of its object type.
基本类型有对齐要求:
3.9.1 Fundamental types [basic.fundamental]
3.9.1/3 For each of the signed integer types, there exists a corresponding (but different) unsigned integer type: "unsigned char", "unsigned short int", "unsigned int", and "unsigned long int," each of which occupies the same amount of storage and has the same alignment requirements (3.9) as the corresponding signed integer type;...
填充 可能 由于 "implementation alignment requirements":
9.2 Class members [class.mem]
9.2/12 Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).
9.2/12中的"allocated"和3.9/5中的"allocated"是同一个意思吗?规范中 "allocated" 的大多数使用是指动态存储分配,而不是结构内部布局。在 9.2/12 中使用 may 似乎暗示 3.9/5 和 3.9.1/3 的对齐要求可能并不严格要求结构成员。
POD 结构的第一个成员将根据结构的对齐要求进行对齐:
9.2/17 A pointer to a POD-struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [Note: There might therefore be unnamed padding within a POD-struct object, but not at its beginning, as necessary to achieve appropriate alignment. ]
[在以上所有引号中添加了强调。]
POD结构的每个元素本身就是一个对象,只能根据这些对象的对齐要求分配对象。但是,对齐要求可能会发生变化,因为某些东西是另一个对象的子对象 ([basic.align]/1, 2:
1 Object types have alignment requirements (3.9.1, 3.9.2) 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 alignment specifier (7.6.2).
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(std::max_align_t)
(18.2). The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject. [Example:struct B { long double d; }; struct D : virtual B { char c; }
When
D
is the type of a complete object, it will have a subobject of typeB
, so it must be aligned appropriately for along double
. IfD
appears as a subobject of another object that also hasB
as a virtual base class, theB
subobject might be part of a different subobject, reducing the alignment requirements on theD
subobject.—end example ] The result of thealignof
operator reflects the alignment requirement of the type in the complete-object case.
[强调已添加]
虽然示例通过继承引用子对象,但规范的措辞只是泛指子对象,所以我相信同样的规则适用,所以一方面你可以 假设每个子对象都对齐以便可以访问。另一方面,不,你 不能 必然假设这与 alignof
给你的对齐方式相同。
[参考来自N4296,但我相信这同样适用于所有最新版本。当然,C++98/03 根本没有 alignof
,但我相信同样的基本原则适用——成员将对齐以便可以使用,但对齐要求不一定与将它们用作独立对象时相同。]
每种类型都有两个不同的对齐要求。一个对应于完整的对象,另一个对应于子对象。 [basic.align]/2:
The alignment required for a type might be different when it is used as the type of a complete object and when it is used as the type of a subobject. [ Example:
struct B { long double d; }; struct D : virtual B { char c; };
When
D
is the type of a complete object, it will have a subobject of typeB
, so it must be aligned appropriately for along double
. IfD
appears as a subobject of another object that also has B as a virtual base class, theB
subobject might be part of a different subobject, reducing the alignment requirements on theD
subobject. —end example ] The result of thealignof
operator reflects the alignment requirement of the type in the complete-object case.
我想不出成员子对象的任何具体示例 - 但肯定有 none! -,但上面的段落承认了成员子对象的对齐方式比 alignof
更弱的可能性,这将使您的条件失败。