[英]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);
}
联合或结构的全局变量的默认对齐方式是什么。
这取决于工会成员。
它们是否保证字对齐?
否。(假设字为 4 字节)。 对齐要求很复杂。 尽管它们很少大于sizeof(int)
,但它们可能因每种类型而异。
在 C11 中,通过包含max_align_t
对象,联合将根据需要与任何类型对齐。
max_align_t
是一种对象类型,其对齐方式与所有上下文中的实现支持的一样大; 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;
除非您使用例如__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;
...
你可以在这里看到奇怪的地址:
0x804971d * &global_address1
0x8049714
0x8049715 * &global_address2
0x804970c
在一些有严格对齐要求的架构中尝试访问这些地址会导致一些未对齐的访问异常并停止程序。 其他可以处理未对齐访问的架构,以性能为代价,将需要至少两个内存读取周期,需要多个 CPU 周期才能完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.