C中的默认联合和结构对齐?

Default union and structure alignment in C?

作为联合或结构的全局变量的默认对齐方式是什么。他们保证字对齐吗?特别是在使用 GCC 和 SDCC 时。

在代码中,函数f()是否安全,是否会导致未对齐访问? 16 位和 32 位平台有区别吗?

#define ADDR_SIZE 8

typedef union {
   unsigned char u8[ADDR_SIZE];
} addr_t;

addr_t global_address;

void f(void) {
   uint32_t x = *((uint32_t *)&global_address) + *((uint32_t *)&global_address + 1);
}

除非您使用例如 __attribute__((aligned(4))) 指定对齐要求,否则您不能保证并集正确对齐。

使用 char 仔细安排全局变量,如下所示:

...
#define ADDR_SIZE 8

typedef union {
   unsigned char u8[ADDR_SIZE];
} addr_t;

addr_t global_address1;
char padd1;
addr_t global_address2;
addr_t global_address3;
...

您可以see这里的奇数地址:

0x804971d * &global_address1
0x8049714
0x8049715 * &global_address2
0x804970c

在某些具有严格对齐要求的体系结构中尝试访问这些地址将导致一些未对齐的访问异常并停止程序。其他可以以性能成本处理未对齐访问的架构将需要至少两个内存读取周期 需要多个 CPU 周期才能完成。

What is the default alignment of global variables that are unions or structures.

这取决于工会成员。

Are they guaranteed to be word-aligned?

没有。 (假设字是 4 字节)。对齐要求很复杂。尽管它们很少大于 sizeof(int),但它们可能因类型而异。


在 C11 中,通过包含一个 max_align_t 对象,联合将根据需要与任何类型对齐。

max_align_t which is an object type whose alignment is as great as is supported by the implementation in all contexts; C11 §7.19 2

#include <stddef.h>

typedef union {
   max_align_t dummy;
   unsigned char u8[ADDR_SIZE];
} addr_t;

@Jens Gustedt 有关于别名的优点。只需从联合内访问 uint32_t。注意字节序问题。

typedef union {
   unsigned char u8[ADDR_SIZE];
   uint32_t u32[ADDR_SIZE/sizeof(uint32_t)];
} addr_t;