C++ sizeof(T)==sizeof(int)吗?
我一直在仔细研究标准草案,似乎找不到我想要的 如果我有一个标准的布局类型C++ sizeof(T)==sizeof(int)吗?,c++,arrays,sizeof,C++,Arrays,Sizeof,我一直在仔细研究标准草案,似乎找不到我想要的 如果我有一个标准的布局类型 struct T { unsigned handle; }; 然后我知道对一些t 目标是创建一些向量v,并将&v[0]传递给C函数,该函数需要指向无符号整数数组的指针 那么,标准是否定义了sizeof(T)==sizeof(unsigned),这是否意味着T数组的布局与unsigned数组的布局相同 虽然讨论了一个非常类似的主题,但我要问的是一个具体的案例,其中数据成员和类都是标准布局,而数据成员是基本类型 我读过
struct T {
unsigned handle;
};
然后我知道对一些t代码>
目标是创建一些向量v
,并将&v[0]
传递给C函数,该函数需要指向无符号整数数组的指针
那么,标准是否定义了sizeof(T)==sizeof(unsigned)
,这是否意味着T
数组的布局与unsigned
数组的布局相同
虽然讨论了一个非常类似的主题,但我要问的是一个具体的案例,其中数据成员和类都是标准布局,而数据成员是基本类型
我读过一些段落,这些段落似乎暗示这可能是真的,但没有什么是一针见血的。例如:
§9.2.17
两种标准布局结构(第9条)类型在以下情况下是布局兼容的:
它们具有相同数量的非静态数据成员和相应的
非静态数据成员(按声明顺序)与布局兼容
类型
这不是我想要的,我不认为。我已经习惯了Borland的环境,对他们来说:
在您的例子中,T是一个结构,所以sizeof(T)是结构的大小
- 这取决于编译器的#pragma pack和align设置
- 因此,有时它可以大于sizeof(未签名)李>
如果您有4字节的结构(uint32)和16字节的allign,原因也是一样的
- 结构T{uint32 u;}李>
- 那么ta[100]与uint32 a[100]不一样李>
- 因为T是uint32+12字节的空白李>
考虑到以下情况,您基本上是在问:
struct T {
U handle;
};
是否保证sizeof(T)==sizeof(U)
。不,不是
ISO C++03标准第9.2/17节规定:
指向POD结构对象的指针,使用
重新解释\u cast
,指向其初始成员(或者如果该成员是
位字段,然后输入到它所在的单元),反之亦然
假设您有一个struct
数组。反之亦然,表示任何T::handle
成员的地址也必须是struct
的有效地址。现在,假设这些成员的类型为char
,并且您的声明是正确的。这意味着struct
将被允许有一个未对齐的地址,这似乎不太可能。标准通常试图不以这种方式束缚实现。要使您的声明为真,标准必须要求允许struct
具有未对齐的地址。而且它必须被允许用于所有结构,因为struct
可以是一个前向声明的不透明类型
此外,第9.2/17节继续说明:
[注意:因此,POD struct对象中可能会有未命名的填充,但不会在其开头,这是实现适当对齐所必需的。]
从另一个角度来看,这意味着不能保证永远不会有填充。收回:这个论点是错误的。引理2的证明依赖于一个隐藏的前提,即聚合类型的对齐严格取决于其成员类型的对齐。因此,该标准不支持该前提。因此,允许struct{Foo f}
具有比Foo
更严格的对齐要求
我在这里扮演魔鬼代言人的角色,因为似乎没有其他人愿意。我认为标准C++()保证<代码> SIEZOF(t)= sisiof(u)< /> >当代码> t>代码>是标准布局类(9/7),默认对齐方式有一个默认的默认对齐非静态数据成员<代码> u>代码>,例如,
struct T { // or class, or union
U u;
};
众所周知:
sizeof(T)>=sizeof(U)
偏移量(T,u)==0
(9.2/19)
U
必须是标准布局类型,才能使T
成为标准布局类
u
有一个表示法,它完全由sizeof(u)
连续的内存字节(1.8/5)组成
这些事实加在一起意味着T
表示的第一个sizeof(U)
字节被U
表示占据。如果sizeof(T)>sizeof(U)
,则多余的字节必须是尾部填充:在T
中的U
表示形式之后插入未使用的填充字节
简言之,论点是:
- 该标准详细说明了实现可以向标准布局类添加填充的情况
- 所有这些情况都不适用于这种特殊情况,因此
- 一致性实现不能添加填充
潜在的填充源
在什么情况下,标准允许实现将此类填充添加到标准布局类的表示中?当需要对齐时:根据3.11/1,“对齐是一个实现定义的整数值,表示连续地址之间可以分配给给定对象的字节数。”有两次提到添加填充,都是出于对齐的原因:
- 5.3.3 Sizeof[expr.Sizeof]/2声明“当应用于引用或引用类型时,结果为引用类型的大小。当应用
对于一个类,结果是该类对象中的字节数,包括将该类型的对象放入数组所需的任何填充。最派生类的大小应大于零(1.8)。将
sizeof
应用于基类子对象的结果是基类类型的大小。77应用于数组时,结果是数组中的总字节数。