sizeof一个结构体,如果有内嵌的结构体,按照什么方式对齐?

vsdfad 2016-01-04 06:45:26
好像说,sizeof()的计算结果,按照struct当中最大的成员size的整数倍对齐。

1. C++标准有这个说法吗? 准确说法是什么?
2. 如果一个struct又包含了另一个结构体,那么是不是还是按照内嵌结构体当中所有成员的大小,以及普通类型成员的大小,选出一个最大值,sizeof就是这个最大值的整数倍?

我做了一个实验:

struct A{char m1;char m2;char m3;};
struct B{A m1;char m2;};
struct C{A m1;short m2;};
struct D{A m1;int m2;};
cout<<sizeof(B)<<endl;
cout<<sizeof(C)<<endl;
cout<<sizeof(D)<<endl;

结果是4,6,8.
看起来,对于sizeof(C)而言,因为C有一个short成员,所以按照short对齐了? 同理可知sizeof(D)?

我如果把A改成struct A{short m1;char m2;short m3;};那么B按照short对齐就是8,C也是8
而D还是要按照int对齐,所以是12。

不知道我的猜测是否符合语言规范。
...全文
177 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
paschen 版主 2016-01-05
  • 打赏
  • 举报
回复
结构体的对齐是取数据成员中最大的与你设置的值(可以项目属性中设置或者#pragma pack()设置)的最小值作为对齐大小的
赵4老师 2016-01-05
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码!
#include <stdio.h>
#define field_offset(s,f) (int)(&(((struct s *)(0))->f))
struct AD  { int a; char b[13]; double c;};
#pragma pack(push)
#pragma pack(1)
struct A1  { int a; char b[13]; double c;};
#pragma pack(2)
struct A2  { int a; char b[13]; double c;};
#pragma pack(4)
struct A4  { int a; char b[13]; double c;};
#pragma pack(8)
struct A8  { int a; char b[13]; double c;};
#pragma pack(16)
struct A16 { int a; char b[13]; double c;};
#pragma pack(pop)
int main() {
    printf("AD.a %d\n",field_offset(AD,a));
    printf("AD.b %d\n",field_offset(AD,b));
    printf("AD.c %d\n",field_offset(AD,c));
    printf("\n");
    printf("A1.a %d\n",field_offset(A1,a));
    printf("A1.b %d\n",field_offset(A1,b));
    printf("A1.c %d\n",field_offset(A1,c));
    printf("\n");
    printf("A2.a %d\n",field_offset(A2,a));
    printf("A2.b %d\n",field_offset(A2,b));
    printf("A2.c %d\n",field_offset(A2,c));
    printf("\n");
    printf("A4.a %d\n",field_offset(A4,a));
    printf("A4.b %d\n",field_offset(A4,b));
    printf("A4.c %d\n",field_offset(A4,c));
    printf("\n");
    printf("A8.a %d\n",field_offset(A8,a));
    printf("A8.b %d\n",field_offset(A8,b));
    printf("A8.c %d\n",field_offset(A8,c));
    printf("\n");
    printf("A16.a %d\n",field_offset(A16,a));
    printf("A16.b %d\n",field_offset(A16,b));
    printf("A16.c %d\n",field_offset(A16,c));
    printf("\n");
    return 0;
}
//AD.a 0
//AD.b 4
//AD.c 24
//
//A1.a 0
//A1.b 4
//A1.c 17
//
//A2.a 0
//A2.b 4
//A2.c 18
//
//A4.a 0
//A4.b 4
//A4.c 20
//
//A8.a 0
//A8.b 4
//A8.c 24
//
//A16.a 0
//A16.b 4
//A16.c 24
//
//
fefe82 2016-01-05
  • 打赏
  • 举报
回复
标注并没有规定一定要怎么做。 编译器实现的话,一般会在满足每一个成员对齐要求的情况下,加入尽可能少的填充。
principl 2016-01-05
  • 打赏
  • 举报
回复
给个参考链接:http://www.cnblogs.com/motadou/archive/2009/01/17/1558438.html,理解其原理,另外这个仅限于C。C++更复杂。
yshuise 2016-01-04
  • 打赏
  • 举报
回复
struct B{A m1;char m2;}; ====================== 把A m1;当做最大项来看,也就是其整数倍

64,643

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧