访问未对齐union的低对齐要求成员是否触发未定义行为?
C语言中未对齐指针与Union的未定义行为分析
1. 普通数组的未对齐int访问:明确的未定义行为
当通过强制转换得到未对齐的int*并解引用时,无论是否越界,行为都是未定义的:
int x[2]; // 假设 CHAR_BIT == 8 且 sizeof(int) == 4 *(int *)((char *)x+1) = 10; // 未对齐指针解引用,属于未定义行为
这是因为int类型有严格的对齐要求(通常与sizeof(int)一致),未对齐的访问会触发硬件异常或不可预测的行为。
2. Union指针未对齐后访问int成员:依然是未定义行为
对于包含int成员的union,union的对齐要求继承自其成员中最严格的那个(即int的对齐要求)。当你将未对齐地址强制转换为union X*并访问其int成员时,本质还是在访问未对齐的int,因此行为仍是未定义的:
union X { int i; char c[4]; } x[2]; ((union X *)((char *)x+1))->i = 10; // 未定义行为,访问未对齐的int
3. Union指针未对齐后访问char成员:仍属于未定义行为
你提到的这段代码:
((union X *)((char *)x+1))->c[0] = 10;
依然是未定义行为,原因在于:
union X的对齐要求等同于int的对齐要求,这意味着union X*类型的指针必须指向满足int对齐要求的地址。- 当你将未对齐的地址强制转换为
union X*时,这个指针本身是无效的——它并未指向一个符合union X对齐要求的对象或存储区。 - 解引用这个无效指针(即使只是访问其中对齐要求为1的
char成员),已经违反了C标准对指针有效性的要求,因此行为是未定义的。
简单来说:虽然访问char本身不需要严格对齐,但你是通过一个不符合union对齐要求的union指针来访问的,这种指针的解引用操作本身就已经触发了未定义行为,和你访问哪个成员无关。
内容的提问来源于stack exchange,提问作者CPlus
相关产品推荐
相关产品推荐

