2

我的编译器要求我有一个内存对齐的结构声明,以确保正确的数据访问。我有一个顶层结构,它由一些其他结构组成。确保顶部结构与 32 字节边界对齐是否足够,或者我需要确保每个结构都应与 32 字节边界对齐。代码片段如下:-

typedef struct {
   int p;
   int q;
   char n;
} L;

typedef struct {
   int c;
   int d;
   char e;
   L    X2[13];
} B;

typedef struct {
   int a;
   int b;
   B   X1[10];
} M;

为了确保正确的数据访问,我是否需要确保所有结构都正确对齐内存,或者填充最顶部的结构将确保内存对齐。

4

3 回答 3

2

有时您的应用程序可能需要特定的布局,但如果在这种情况下如您所说,这是编译器的要求(或者更准确地说可能是编译器的目标架构),那么编译器有责任确保满足这些要求。

如果您需要编译器根据目标要求自然强制执行的对齐方式,您将需要编译器特定的指令来打包和对齐;然而,应用这样的指令并弄错比让编译器处理它更容易导致对齐错误。如果您尝试通过添加自己的填充成员来对齐,它可能会起作用,但不是必需的,编译器也可能会插入自己的额外填充。

关键是编译器不会生成一个结构,其成员无法安全有效地寻址。它将在成员之间插入任何必要的填充,以确保后续成员是可寻址的。

如果你不相信它会起作用,让你的链接器输出一个映射文件(如果它还没有这样做的话)并检查这些符号的地址以验证正确的对齐方式。还要查看结构的生成大小;您可能会发现其中一些大于它们各部分的总和——即编译器通过插入填充来强制对齐。

于 2012-07-17T20:27:24.237 回答
0

如果您可以使用它,如果您的应用程序(或架构或性能)需要它,C11 有对齐声明:http ://en.wikipedia.org/wiki/C11_%28C_standard_revision%29

  • 对齐规范(_Alignas 说明符、alignof 运算符、aligned_alloc 函数、头文件)

GCC 肯定也有扩展。

于 2012-07-17T21:04:26.823 回答
0

如果要使用自然对齐,则必须对字段进行排序并手动填充到自然字长。不保证可移植性,但对于特定的处理器,这是可以做到的(在嵌入式世界中并不罕见)。如果 sizeof(int) 为 4,则必须向子结构添加填充以确保数组对齐(我假设您的目标是避免编译器添加的“秘密”填充?)。例如 :

typedef struct {
   int p;
   int q;
   char n;
   char pad[3];
} L;

typedef struct {
   int c;
   int d;
   char e;
   char pad[3];
   L    X2[13];
} B;

typedef struct {
   int a;
   int b;
   B   X1[10];
} M;

通常不会导致结构中的“隐藏”对齐。

于 2012-07-24T17:25:27.527 回答