结构体对齐

5
#define MAX_SIZE 8

enum my_enum
{
    VAL1 = 0;
    VAL2,
    VAL3,
    VAL4,
    VAL_MAX
};

struct my_struct
{
  enum my_enum e;
  int  w[MAX_SIZE];
};

在目标平台上,这种结构的布局是否会导致对齐问题?我知道这很大程度上取决于平台,但通常情况下C编译器允许对结构进行填充,因此例如在32位机器上,其中'int'长度为32位:

struct my_struct
{
    int w[MAX_SIZE];
}

据我了解,结构体被对齐,编译器可能不会对其布局进行其他操作,但在结构体中添加“枚举my_enum”可能会使该结构体在这种机器上变得不对齐。 我应该采取任何特殊措施来避免这种情况吗?是否应该完全避免它?

非常感谢您的澄清!

马克


1
如果您认为结构体仅仅是元素的总和,那么您就需要担心了。例如,struct my_struct *p = malloc(sizeof(my_enum)+n*sizeof(int)) 尝试分配少于 MAX_SIZE 个整数。但是,如果存在填充,则最终分配的空间将不足。 - ugoren
3个回答

6
答案是否定的,您不需要做任何事情。如果添加字段会破坏对齐,则编译器将在适当的位置应用填充以重新对齐。
在您的情况下,枚举可能会被实现为int,因此您首先不会遇到此问题。
更好的例子是:
struct my_struct
{
  char ch;
  int  w[MAX_SIZE];
};

在这种情况下,编译器很可能会在ch后面添加3个字节的填充以使w对齐到4个字节。

0

您无需担心尝试不引入填充。如果您想通过演示结构成员的顺序是否会产生差异来进行实验,则可以尝试 this。(它不旨在演示特定实现的行为。)

根据C11标准,所有对齐方式都是2的幂。

简单的数学规律表明,除非无法创建此类对象的数组,否则对象的对齐要求不可能超过其大小。


0

不,你不必考虑对齐问题是否能正常工作。基本上,这取决于编译器将事物对齐以适应目标平台的方式。如果它很聪明,甚至会以允许最大性能的方式来做。

例如,如果你有一个char,然后是一个整数,而目标平台允许不对齐的加载/存储,编译器可能会生成大小为5个字节的结构,其中整数是不对齐的。如果你想保证4字节对齐,你需要这样做:

struct my_struct {
  char a;
  char dummy[3];
  int b;
}

或者将数据类型从大到小放置在结构体中,以获得最佳性能。

编辑:有人指出规范可能已经对此行为进行了严格限制,因此现代编译器几乎都会将所有内容对齐到自然边界。


编译器可以或者不可以在“自然”边界上对成员进行排列。它必须以这样的方式对所有成员进行排列,使得它们能够被正确访问。例如,给定struct my_struct obj; int *ptr = &obj.b;,对*ptr的引用必须有效。(特定于编译器的打包指示和属性可能会破坏这一点;例如,请参阅此问题。) - Keith Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接