免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 24637 | 回复: 35
打印 上一主题 下一主题

关于gcc中字节对齐的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-28 14:04 |只看该作者 |倒序浏览

  1. #include<stdio.h>

  2. struct A
  3. {
  4. double l;
  5. int i;
  6. int b;
  7. char c;
  8. };

  9. int main()
  10. {
  11.         struct A m[2];
  12.         printf("%d\n", sizeof(struct A));
  13.         printf("%p\n", &m[0]);
  14.         printf("%p\n", &m[1]);
  15.         printf("%d\n", (int)&m[1]-(int)&m[0]);

  16.         printf("%p\n", &(m[0].l));
  17.         printf("%p\n", &(m[1].l));

  18.         return 0;
  19. }

复制代码


对于上面的代码, 在VC中,结构体A的大小为24, 但是在gcc 中其大小却为20, 这样, 我连续分配两个这个结构体时, 第二个结构体的起始就不是double大小的倍数.  请问为什么在gcc中不将其进行8位对齐? 谢谢.
gcc version
gcc version 4.1.1 20061011 (Red Hat 4.1.1-30)

论坛徽章:
0
2 [报告]
发表于 2007-06-28 14:06 |只看该作者

回复 1楼 scutan 的帖子

下面的是运行结果

  1. 20
  2. 0xbff4a19c
  3. 0xbff4a1b0
  4. 20
  5. 0xbff4a19c
  6. 0xbff4a1b0
复制代码

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
3 [报告]
发表于 2007-06-28 14:36 |只看该作者
原帖由 scutan 于 2007-6-28 14:04 发表
[CODE]
#include<stdio.h>

struct A
{
double l;
int i;
int b;
char c;
};

int main()
{
        struct A m[2];
        printf("%d\n", sizeof(struct A));
        pri ...

楼主用的是 x86 系列的平台吧,x86 的对齐要求不是那么的严格。换其他平台看看。

论坛徽章:
0
4 [报告]
发表于 2007-06-28 14:42 |只看该作者
原帖由 MMMIX 于 2007-6-28 14:36 发表

楼主用的是 x86 系列的平台吧,x86 的对齐要求不是那么的严格。换其他平台看看。



哦, 不过我这儿也就只有X86平台. 呵呵.
也是, 毕竟字节对齐主要的为了在存取时能够更快速.

论坛徽章:
0
5 [报告]
发表于 2007-06-28 14:56 |只看该作者
原帖由 scutan 于 2007-6-28 14:04 发表
[CODE]
#include<stdio.h>

struct A
{
double l;
int i;
int b;
char c;
};

int main()
{
        struct A m[2];
        printf("%d\n", sizeof(struct A));
        pri ...

每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。在lz的程序中,n默认是4。
在这个前提下分析lz得到的结果:

4字节对齐(#pragma pack(4))
sizeof(m[0]) = 20;
分析过程:
1)成员数据对齐
struct A {
  double l;        /* 长度8 > 4 按4对齐;起始offset=0 0%4=0;存放位置区间[0,7] */
  int i;            /* 长度4 = 4 按4对齐;起始offset=8 8%4=0;存放位置区间[8,11] */
  int b;           /* 长度4 = 4 按4对齐;起始offset=12 12%4=0;存放位置区间[12,15] */
  char c;         /* 长度 1 = 4 按1对齐;起始offset=16 16%1=0;存放位置区间[16] */
};
成员总大小为17,
整体对齐系数=min(max (double, int, char), 4) = 4;
整个结构体的大小=20,为什么不是上面算出来的17呢?这里涉及到一个叫做“圆整”的概念。
什么叫“圆整”?比如在这个例子,从17开始,看看那个位置可以被“整体对齐系数(4)”整除,17,18,19都不合适,所以到20,圆整结束。
这也解释了为什么第二个结构体开始的位置不能被8整除,其实只要个能被4整除就可以了。

论坛徽章:
0
6 [报告]
发表于 2007-06-28 15:07 |只看该作者

回复 5楼 zwylinux 的帖子

哦. 明白了, 原来是给它定义成了4. 谢谢!

论坛徽章:
0
7 [报告]
发表于 2007-06-28 18:10 |只看该作者
问得好 ,答得也好

论坛徽章:
0
8 [报告]
发表于 2007-06-28 20:02 |只看该作者
原帖由 zwylinux 于 2007-6-28 14:56 发表

每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。在lz的程序中,n默认是4。
在 ...


gcc 可以用#pragma pack(n) ??

论坛徽章:
0
9 [报告]
发表于 2007-06-28 20:18 |只看该作者
gcc中可以使用

  1. #pragma pack(8)
复制代码

但是我使用了

  1. #pragma pack(8)
复制代码

得到的结果仍然和不使用这一句是一样的, 就是说仍然不是从8的倍数开始的.
请问这是怎么回事呢?
谢谢

[ 本帖最后由 scutan 于 2007-6-28 20:19 编辑 ]

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
10 [报告]
发表于 2007-06-28 20:25 |只看该作者
原帖由 antonym55 于 2007-6-28 20:02 发表


gcc 可以用#pragma pack(n) ??

可以,但并不赞成。

BTW, #pragma pack(n) 是在 gcc 4 中增加的,至少 gcc 3.4 没有这个。

[ 本帖最后由 MMMIX 于 2007-6-29 12:55 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP