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 packalign设置
  • 因此,有时它可以大于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应用于数组时,结果是数组中的总字节数。