【问题标题】:Padding in union is present or not联合中的填充是否存在
【发布时间】:2013-05-20 21:40:57
【问题描述】:

大家好,
我想知道联合是否使用填充?
由于union的大小是最大的数据成员大小,最后能不能有padding?

【问题讨论】:

  • 简而言之,是的!!在我的 Windows 系统上,联合填充的大小是 int 大小的倍数,即 4 字节。因此,除非您使用#pragma pack(1),否则大小为 3 字节的联合将再填充一个字节以产生 4 字节。写一个程序并在发布问题之前尝试一下。
  • "一个联合被填充为整数的倍数,即 4 个字节。"但在这种情况下 union ab{ char a; }一种;大小为 1
  • 在你的情况下根本没有填充。谁说padding 总是完成?就像丹尼尔菲舍尔说的那样,它不是标准强制
  • union u{unsigned a:21;}; - 这个联合在我的 Windows 系统上是 4 个字节,除非我使用 #pragma pack(1),如果我使用它,则为 3 个字节。

标签: c struct padding unions


【解决方案1】:

因为联合的大小是最大的数据成员大小

这不一定是真的。考虑

union Pad {
    char arr[sizeof (double) + 1];
    double d;
};

该联合的最大成员是arr。但通常,double 将在 4 或 8 个字节的倍数上对齐(取决于 double 的架构和大小)。在某些架构上,这甚至是必要的,因为它们根本不支持未对齐读取。

所以sizeof (union Pad) 通常大于sizeof (double) + 1 [通常在 64 位系统上为 16 = 2 * sizeof (double),在 32 位系统上为 16 或 12(在具有 8 位 char 和64 位 doubledouble 所需的对齐可能仍然只有四个字节)]。

这意味着联合中必须有填充,并且只能放在末尾。

通常,union 的大小将是不小于最大成员的任何成员所需的最大对齐的最小倍数。

【讨论】:

  • 但是当我们将 char arr[sizeof(double)+1] 单独合并时,它只给出 size: 9?
  • 标准没有强制要求,允许实现添加填充,但通常(使用 8 字节 doubles),是的,大小为 9。
  • 有没有人设法证明这个例子会很好? - 问是因为我认为没有任何理由在这里填充,好像两个成员之间不需要有空间,它应该只选择最大的一个。
  • @ideasman42 您可以通过编写并运行一个打印出doubleunion Pad 大小的小程序来检查您的编译器是否插入了填充。我从 gcc 和 clang [如预期] 得知,在 64 位系统上,联合的大小是 double (16 = 2*8) 大小的两倍。填充的原因是对齐(两者都在八字节边界上对齐double)。
  • 有趣,它确实对齐,但是如果将double d 替换为char d[sizeof(double)],则不会填充联合。 (至少是 linux/gcc)
【解决方案2】:

当我们在其中使用原始类型时的联合

union
{
    char c;
    int x;
}

它似乎不使用填充,因为最大尺寸的数据无论如何都与边界对齐。

但是当我们在联合中嵌套一个结构时,它会这样做。

    union u
    {
        struct ss
        {
            char s;
            int v;
        }xx;
    }xu;

结果是 8 号。

所以你的问题的答案是 PADDING 在 UNION 中存在。

【讨论】:

  • 正如丹尼尔所说,这是错误的。您将 struct 的填充称为 union 的填充,这是一种误导。
猜你喜欢
  • 2018-06-06
  • 2017-03-14
  • 2023-03-29
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 2010-11-14
相关资源
最近更新 更多