Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 工会内部结构的填充是如何工作的?_C_Struct_Padding_Unions_Memory Alignment - Fatal编程技术网

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

C 工会内部结构的填充是如何工作的?,c,struct,padding,unions,memory-alignment,C,Struct,Padding,Unions,Memory Alignment,我有以下资料: #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

我有以下资料:

#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]);
}
#包括
类型定义联合u_数据
{
结构
{
INTA;
int b;
INTC;
};
国际元素[3];
}我的大学数据;
内部主(空)
{
我的数据;
数据a=3;
数据b=5;
数据c=-3;
printf(“%d,%d,%d\n”,data.elem[0],data.elem[1],data.elem[2]);
}
它与我预期的输出一样:
3,5,-3

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

正如您正确指出的那样,您不能期望
a
b
c
由于填充而与
元素
数组对齐

任何依赖相反的代码都不是可移植的C

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

没有

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

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

可以在
struct
的成员之间引入填充,以强制执行成员的单独对齐要求


它的工作原理和我预期的一样

在您的例子中,似乎已经满足了成员的对齐要求,因此没有引入填充,这导致数组与
结构
完美地映射

这是否意味着结构中的元素可能并不总是对齐 使用阵列

否,因为可能会在
结构的成员之间引入填充
  • 首先,C,C11 6.5.2.3中有一条特殊规则“通用初始顺序”适用于活接头:

    为了简化工会的使用,有一个特别的保证:如果工会包含 几个结构共享一个共同的初始序列(见下文),如果联合 对象当前包含其中一个结构,允许它检查公共 它们中任何一个的起始部分,即完整的联合类型声明 是可见的

    但此规则不适用于此处,因为您的案例是一个结构和一个数组。如果它是两个结构,规则就会适用

  • 实际上,结构可能有填充,因此如果数组与结构的对齐方式不同,则不能保证获得正确的输出。这是实现定义的行为

  • 在C(与C++不同),C116.5.2.3/3中,如果这两种类型是兼容的,那么向结构写入和从数组读取是很好的,并且定义良好。只有在没有填充字节的情况下,结构才能与数组兼容

  • “严格别名”在此处不适用


  • 概要:这是实现定义的行为。如果编译器保证,您可以依赖特定系统上的特定行为。代码将不可移植。

    访问与上次写入的工会成员不同的工会成员会导致未定义的行为。所以:是的,在“可能是鼻恶魔”的意义上。@Yunnosch No,C标准对工会例外(不包括可能的陷阱表示)。这里问的填充问题是另一个问题。就像我问的原因一样。。。我最初看到第二条评论是我在做什么doing@user694733我承认我可能错了。但是,你能更详细地解释一下,关于gsamaras的向上投票(和向下投票)的回答,似乎也是这样。相关的区别是什么?@Yunnosch谈到了工会成员的访问权限。到目前为止,这个问题只有30个观点,所以现在用投票来衡量正确性还为时过早。所有这些听起来都非常不正确。让我检查一下标准。好的,检查一下标准,答案部分不正确。“当您访问a、b和c时,您应该首先以某种方式对它们进行初始化。”这是不正确的,它不是UB,而是实现定义的。“数组元素没有义务与结构的字段对齐(由于填充)。”是正确的。我最初同意您的意见(除了abc的事情),但是你看到用户694733和我之间的评论线程了吗?(令我惊讶的是)这似乎表明没有未定义的行为。有一个有趣的链接,我决定不尝试语言律师……答案的第一部分和最大部分解释一条不适用且未被询问的规则有用吗?@EricPostFischil是的,因为这里的其他人只是将“其未定义的行为”作为下意识反应发布。C中有很多类型的类型是允许的,并且重要的是指出这些,因为C++程序员往往会出错。在C++中,很多情况下调用UB。