是否保证POD结构或标准布局类型的成员根据其对齐要求进行对齐? [英] Are members of a POD-struct or standard layout type guaranteed to be aligned according to their alignment requirements?

查看:161
本文介绍了是否保证POD结构或标准布局类型的成员根据其对齐要求进行对齐?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个POD结构(在C ++ 03中)或一个标准布局类型(在C ++ 11中),所有成员都有基本的对齐要求,确保每个成员都保证根据其对齐要求?

Given a POD-struct (in C++03) or a standard layout type (in C++11), with all members having a fundamental alignment requirement, is it true that every member is guaranteed to be aligned according to its alignment requirement?

换句话说,对于所有成员 m_k 在{ m0 ,,

In other words, for all members m_k in { m0 ... mn } of standard layout type S,

  struct S {
    T0 m0;
    T1 m1;
    ...
    TN mn;
  };

是以下表达式,保证计算 true

is the following expression guaranteed to evaluate to true?

  (offsetof(S,m_k) % alignof(decltype(S::m_k))) == 0

请给出C ++ 03和C ++ 11的答案并引用标准的相关部分。

Please give answers for both C++03 and C++11 and cite the relevant parts of the standard. Supporting evidence from C standards would also be helpful.

我阅读了C ++ 03标准(ISO / IEC 14882 :2003(E))是关于除了第一成员之外的POD结构内的成员的对齐方面没有提及。相关段落为:

My reading of the C++03 standard (ISO/IEC 14882:2003(E)) is that it is silent regarding the alignment of members within a POD-struct, except for the first member. The relevant paragraphs are:

在规范的语言中,对象是存储区域:

In the language of the specification, an object is a "region of storage":


1.8 C ++对象模型[intro.object]

1.8 The C + + object model [intro.object]

1.8 / 1 C ++程序创建,销毁,引用,访问和操作对象。对象是存储区域。 ...

1.8/1 The constructs in a C + + program create, destroy, refer to, access, and manipulate objects. An object is a region of storage. ...

根据对齐要求分配对象:

Objects are allocated according to their alignment requirement:


3.9类型[basic.types]

3.9 Types [basic.types]

3.9 / 5对象类型具有对齐要求(3.9.1,3.9.2)。完整对象类型的对齐是表示字节数的实现定义的整数值; 一个对象被分配到满足其对象类型的对齐要求的地址。

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基本类型[basic.fundamental]

3.9.1 Fundamental types [basic.fundamental]

3.9.1 / 3对于每个有符号整数类型,存在相应的(但不同的)无符号整数类型:unsigned char,unsigned short int,unsigned int和unsigned long int它占据相同的存储量,并且具有与相应的有符号整数类型相同的对齐要求(3.9); ...

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

填充 可能由于实现对齐要求而发生:

Padding may occur due to "implementation alignment requirements":


class.mem]

9.2 Class members [class.mem]

9.2 / 12分配一个(非联合)类的非静态数据成员,没有插入访问说明符,以便以后的成员具有更高的地址一个类对象。未指定由访问说明符分隔的非静态
数据成员的分配顺序(11.1)。 实施对齐要求可能会导致两个相邻成员不会立即分配;因此可能需要管理虚拟函数(10.3)和虚拟基类(10.1)的空间。

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与3.9 / 5中的分配含义相同?规范中分配的大多数用法是指动态存储分配,而不是结构内部布局。在9.2 / 12中使用可能似乎暗示了结构成员可能不需要严格要求3.9 / 5和3.9.1 / 3的对齐要求。

Does the word "allocated" in 9.2/12 have the same meaning as "allocated" in 3.9/5? Most uses of "allocated" in the spec refer to dynamic storage allocation, not struct-internal layout. The use of may in 9.2/12 seems to imply that the alignment requirements of 3.9/5 and 3.9.1/3 might not be strictly required for struct members.

POD结构的第一个成员将根据struct的对齐要求进行对齐:

The first member of a POD-struct will be aligned according to the alignment requirement of the struct:


17指向使用reinterpret_cast适当转换的POD-struct对象的指针指向它的初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。 [注意:因此,为了实现适当的对齐,可能在POD结构体对象内有未命名的填充,但不是在其开头。

[强调在所有上述引号中添加。]

[Emphasis added in all of the above quotes.]

推荐答案

POD结构本身是一个对象,对象只能根据这些对象的对齐要求进行分配。然而,对齐要求可能会改变,因为某事物是另一个对象的子对象([basic.align] / 1,2:

Each element of a POD struct is itself an object, and objects can only be allocated in accordance with the alignment requirements for those objects. The alignment requirements may change, though, due to the fact that something is a sub-object of another object ([basic.align]/1, 2:


1对象类型具有对齐要求(3.9.1,3.9.2),其对可以分配该类型的对象的地址施加限制。 / em>是一个实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。对象类型对该类型的每个对象施加对齐要求;可以使用对齐说明符来请求更严格的对齐(7.6.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基本对齐由小于或等于实现支持的最大对齐所有上下文,等于 alignof(std :: max_align_t)(18.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; }

D complete对象,它将具有 B 类型的子对象,因此它必须适当地对齐 long double 。如果 D 显示为另一个对象的子对象,该对象也具有 B 作为虚拟基类,
B subobject可能是不同子对象的一部分,减少了 D 子对象的对齐要求。 ] alignof 运算符的结果反映了
complete-object案例中类型的对齐要求。

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 给你。

Although the examples refer to a sub-object via inheritance, the normative wording just refers to sub-objects in general, so I believe the same rules apply, so on one hand you can assume that each sub-object is aligned so that it can be accessed. On the other hand, no you can't necessarily assume that will be the same alignment that alignof gives you.

[引用来自N4296,但我相信这同样适用于所有最新版本。 C ++ 98/03,当然没有 alignof ,但我相信同样的基本原则适用 - 成员将被对齐,所以他们可以使用,但是对齐要求不一定与它们用作独立对象时相同。]

[The reference is from N4296, but I believe the same applies to all recent versions. C++98/03, of course, didn't have alignof at all, but I believe the same basic principle applies--members will be aligned so they can be used, but that alignment requirement isn't necessarily the same as when they're used as independent objects.]

这篇关于是否保证POD结构或标准布局类型的成员根据其对齐要求进行对齐?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆