C结构体中sem_t成员与后续成员间是否会因对齐产生填充?
结构体成员对齐与填充问题解答
你的结构体定义如下:
#include <semaphore.h> #include <stdio.h> #include <stdbool.h> typedef struct key{ sem_t sem; char name[32]; int val1; int val2; char k; int n; } Key;
对齐规则细节纠正
你提到的x64按8字节、x32按4字节对齐是简化后的常见场景,更准确的规则是:
- 结构体成员的起始地址必须是自身大小的整数倍,且平台会限制最大对齐值(x64为8字节,x32为4字节);
- 结构体整体的最终大小必须是其内部最大成员对齐要求的整数倍。
sem_t与name之间是否存在填充
如果sem_t的大小确实为32字节,两者之间不会有填充,理由如下:
- sem_t作为结构体首个成员,起始地址就是结构体的起始地址,天然满足自身对齐要求;
- sem_t大小为32字节,其结束地址为起始地址+32,这个地址是x64(8字节)和x32(4字节)默认对齐值的公倍数,完全符合平台对齐要求;
- char类型及char数组的对齐要求为1字节,任何地址都能满足该要求,因此name会直接紧跟在sem_t之后,中间无填充字节。
跨x32/x64平台的一致性
这种无填充的情况在两个平台下均成立:
- x64平台:32是8的倍数,sem_t结束地址是8的整数倍,满足后续成员的对齐要求;
- x32平台:32是4的倍数,sem_t结束地址是4的整数倍,同样满足后续成员的对齐要求。
额外注意事项
sem_t的大小和对齐属性是平台依赖的,当前Linux下实现通常为32字节,但无法保证所有类Unix系统或未来版本都维持此规格。若sem_t大小发生变化(例如变为28字节),x64平台会自动填充4字节至32(8的倍数),此时name才会跟在填充字节之后。
内容的提问来源于stack exchange,提问作者Raul Sofia
相关产品推荐
相关产品推荐

