我目前正在用C(在Ubuntu x64中)定义一个 struct .它看起来是这样的:

#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中的 struct 成员将与8字节对齐,而x32中的 struct 成员将与4字节对齐.这也是我 Select 32作为id数组大小的原因.

我想知道的是:如果是这样(第一个成员是sem_t(显然是32个字节),下一个成员是sem_t或其他任何东西),第一个(Sem)和第二个成员(在本例中是名称)之间会有任何填充吗?或者它们是连续的?如果是这样,这对x32和x64都适用吗(因为32字节是4字节和8字节的倍数)?

推荐答案

这取决于--取决于实施情况.有一个问题你需要确信你知道答案:你为什么要担心?

sem_t的大小在32位和64位实现之间可能有所不同.通常,当N是2的幂时,N字节对象(或N字节对象数组)将在N字节边界上对齐.double的路由并不总是遵循这一规则.如果您有任何short(或uint16_t)个数据成员,它们只需要在2字节边界*上对齐. struct 或联合类型将根据具有最严格对齐要求的构件的对齐要求进行对齐.

semname之间不会有任何填充字节,因为字符串可以在任何边界上对齐.在nameval1之间可能有填充字节,但您可能已经避免了(部分原因是您 Select 了长度32作为name).

您将拥有介于kn之间的填充;如果颠倒它们的顺序,您将(可能)只拥有尾随填充,但由于单个字符,您将拥有尾随填充.如前所述,您有内部填充(可能有3个字节),也可能没有尾部填充.

要进一步研究,您需要使用<stddef.h>中的offsetof宏,但请注意,它只能报告当前实现,而不能报告其他实现.

* Technically, a 100 need not be 16 bits or 2 bytes, but it almost invariably is, and I'm assuming as much here.

C++相关问答推荐

我可以动态分配具有空类型函数的矩阵吗?

C:gcc返回多个错误定义,但msvc—不""'

为什么复合文字(C99)的返回会生成更多的汇编代码?

如何创建由符号组成的垂直结果图形?

在C++中头文件中声明外部 struct

如何知道我是否从非阻塞套接字读取所有内容

如何将字符**传递给需要常量字符指针的常量数组的函数

进程在写入管道时挂起

如何在C++中处理按键

C指针概念分段故障

是否需要包括<;errno.h>;才能使用perror?

使用TCL C API导航到列表中的元素

如何在不更改格式说明符的情况下同时支持双精度和长双精度?

在Ubuntu上使用库部署C程序的最佳实践

通过char*访问指针的对象表示是未定义的行为吗?

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?

是否可以在多字 C 类型中的任何位置混合存储和类型限定符?

当循环变量在溢出时未定义时,可以进行哪些优化?

返回指向函数内声明的复合文字的指针是否安全,还是应该使用 malloc?

将字节/字符序列写入标准输出的最简单形式