包含位域的结构的大小在不同的编译器上是不同的

时间:2015-08-13 06:41:35

标签: c visual-studio gcc

我在VS和GCC上运行了以下程序。

#include <stdio.h>

int main(void)
{
    struct bitfield
    {
        unsigned a : 3;
        char b;
        unsigned c : 5;
        int d;
    }bit;

    printf("Size = %d\n", sizeof(bit));

    return 0;
}

令我惊讶的是,VS给出16为sizeof结构,GCC给出12。

我的理解是编译器尝试在1行(Bank0,Bank1,Bank2,Bank3)中分配achar bc,在另一行中分配int d行。这似乎表明结构的大小应该是8个字节(假设是32位系统)。

任何人都可以解释这些结果吗?我在64位计算机上运行。

2 个答案:

答案 0 :(得分:1)

编译器只需要将结构中相邻声明的位字段打包到相同的可寻址存储单元中。 (在这种情况下,这可能是一个32位的块,给定32位CPU)。您在它们之间显示了一个char,因此编译器可以随意分配您的结构。

通常,标准字段的位置非常差,因此完全不可移植且不可预测。未指定位分配的顺序。没有指定哪个位是MSB。未指定对齐方式。没有指定位字段是否可以&#34;跨越&#34; a&#34;存储单元&#34;。等等。

此外,struct可以在任何地方包含填充字节。

更好的想法是永远不要使用位字段,而是使用位运算符。

答案 1 :(得分:0)

由于您的系统具有64位架构,因此大多数编译器将填充8个字节 Gcc目前的版本仍然填充4个字节。
此外,结构填充完全取决于编译器。你会在'c'代码中看到许多未定义的行为,比如使用一元增量(pre / post),填充,内存映射等,这完全是编译器和m / c相关的。所以,实际上没有这样的解释 此外,在您的系统上运行以下代码。在这种情况下,VS应该是o / p 24和GCC 16。

#include <stdio.h>

int main(void)
{
    struct bitfield
    {
        unsigned a : 3;
        unsigned c : 5;
        int d;
        char b;
    }bit;

    printf("Size = %d\n", sizeof(bit));

    return 0;
}