简体   繁体   English

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

[英]Default union and structure alignment in C?

What is the default alignment of global variables that are unions or structures.联合或结构的全局变量的默认对齐方式是什么。 Are they guaranteed to be word-aligned?它们是否保证字对齐? In particular when using GCC and SDCC.特别是在使用 GCC 和 SDCC 时。

In the code, is the function f() safe, or can it cause unaligned access?在代码中,函数f()安全,还是会导致未对齐的访问? Is there a difference between 16-bit and 32-bit platforms? 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);
}

What is the default alignment of global variables that are unions or structures.联合或结构的全局变量的默认对齐方式是什么。

It depends on the union members.这取决于工会成员。

Are they guaranteed to be word-aligned?它们是否保证字对齐?

No. (Assuming word is 4-byte).否。(假设字为 4 字节)。 Alignment requirements are complex.对齐要求很复杂。 Although they are rarely greater than the sizeof(int) , they may differ per each type.尽管它们很少大于sizeof(int) ,但它们可能因每种类型而异。


In C11, by including a max_align_t object, the union will be aligned as needed to any type.在 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; max_align_t是一种对象类型,其对齐方式与所有上下文中的实现支持的一样大; C11 §7.19 2 C11 §7.19 2

#include <stddef.h>

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

@Jens Gustedt has good points about aliasing. @Jens Gustedt对混叠有很好的观点。 Just access the uint32_t from within the union.只需从联合内部访问uint32_t Watch out for endian issues.注意字节序问题。

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

Unless you specified the alignment requirements using for example __attribute__((aligned(4))) , you cannot guarantee the union to be aligned properly.除非您使用例如__attribute__((aligned(4)))指定对齐要求,否则您不能保证联合正确对齐。

With careful global variables arrangement using char like here:使用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;
...

You can see here the odd address:你可以在这里看到奇怪的地址:

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

Attempting to access these address in some architectures with strict-alignment requirements will cause some misaligned access exception and halts the program.在一些有严格对齐要求的架构中尝试访问这些地址会导致一些未对齐的访问异常并停止程序。 Other architectures that can handle misaligned access, at performance cost, will require at least two memory read cycles witch requires a number of CPU cycles to complete.其他可以处理未对齐访问的架构,以性能为代价,将需要至少两个内存读取周期,需要多个 CPU 周期才能完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM