工会内部结构的填充如何工作?

问题描述 投票:4回答:4

我有以下内容:

#include <stdio.h>

typedef union u_data
{
        struct
        {
                int a;
                int b;
                int c;
        };
                int elem[3];
}       my_data;

int     main(void)
{
        my_data data;

        data.a = 3;
        data.b = 5;
        data.c = -3;
        printf("%d, %d, %d\n", data.elem[0], data.elem[1], data.elem[2]);
}

它的工作原理与我预期的输出:3, 5, -3

但我知道结构可以有填充,所以这意味着结构中的元素可能不总是与数组对齐?

c struct padding unions memory-alignment
4个回答
3
投票
  • 首先,C,C11 6.5.2.3中的工会有一个特殊的规则“共同初始序列”: 为了简化联合的使用,我们做了一个特殊的保证:如果一个联合包含多个共享一个共同初始序列的结构(见下文),并且如果联合对象当前包含这些结构中的一个,则允许检查共同其中任何一个的初始部分都可以看到完整类型的联合声明。 这条规则不适用于此,因为您的案例是结构和数组。如果它是两个结构,那么规则就适用了。
  • 实际上,结构可能有填充,因此如果数组的排列方式与结构不同,则无法保证获得正确的输出。这是实现定义的行为。
  • 写入结构并从数组中读取很好并且在C(与C ++不同)C11 6.5.2.3/3中定义良好,因为这两种类型是兼容的。如果没有填充字节,则结构只能与数组兼容。
  • “严格别名”不适用于此处。

简介:这是实现定义的行为。如果编译器保证,您可以依赖某个系统上的某个行为。代码不可移植。


2
投票

你正确地指出,你不能指望abcelem阵列对齐由于填充。

任何依赖相反的代码都不是便携式的C.


0
投票

可以在struct的成员之间引入填充以强制执行成员的个体对齐要求。


它按我的预期工作

看起来在你的情况下,成员的对齐要求已经实现,因此没有引入填充,这导致数组映射完美的struct

这是否意味着结构中的元素可能并不总是与数组对齐?

不,因为可以在struct的成员之间引入填充。


-2
投票

这是否意味着结构中的元素可能并不总是与数组对齐?

没有。

您的代码调用未定义的行为。

数组elem没有义务将(由于填充)对齐到结构的字段。

© www.soinside.com 2019 - 2024. All rights reserved.