2016-09-23 72 views
2

我有这两种结构: - 1.位字段中联合在结构

typedef struct bitfield 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union 
    {  
     unsigned int c:4; 
     unsigned int d:32; 
    }; 
}bfield; 

这种结构具有匿名联合,当我计算该结构的尺寸 - 它出来是12个字节( 4 + 4 + 4)。这可以。

2.

typedef struct bitfield 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union u 
    {  
     unsigned int c:4; 
     unsigned int d:32; 
    }; 
}bfield; 

但在32位机器打印该结构的大小的8个字节我DEVC++编译器。我不明白为什么它会是8.

+0

几乎没有关于位域布局的保证。说:32位'无符号'你的'结构'只能有8个字节,如果你的字节超过8位宽。请提供[mcve]。假设8位/字节,“struct”大小可以很好地为16个字节。但这一切都取决于平台。 – Olaf

+0

@Olaf无符号的默认宽度不相关,因为他/她已经手动指定了每个字段的位宽。但我仍然同意,不可能将其打包为只有8个字节。看到编译器生成什么代码将是有趣的。 – jforberg

+0

但是我得到了与OP相同的结果:goo.gl/ASQO6Q – jforberg

回答

2

OP中的联合声明是不正确的(它不会执行OP想要的)。

它看起来只是一个联合声明,并没有添加一个字段到结构中。

要么将​​联合字段声明为匿名,要么声明为named。

请参见本例中(这里还张贴:http://rextester.com/EPUEH77041

在这两种情况下,结构的大小为12个字节。

#include <iostream> 

typedef struct bitfield 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union u 
    {  
    unsigned int c:4; 
    unsigned int d:32; 
    }U; 
}bfield; 


typedef struct bitfield2 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union 
    {  
    unsigned int c:4; 
    unsigned int d:32; 
    }; 
}bfield2; 

int main() 
{ 
    std::cout << "Test bitfields1\n" << sizeof(bfield) << "\n"; 
    std::cout << "Test bitfields2\n" << sizeof(bfield2) << "\n"; 

    static volatile bfield y; 
    y.a=0x1234; 
    y.b = 0x1FF55; 
    y.U.d = 0x5a5a5a5a; 
    std::cout << std::hex << y.U.d << "\n"; 

    static volatile bfield2 x; 
    x.a=0x1234; 
    x.b = 0x1FF55; 
    x.d = 0x5a5a5a5a; 
    std::cout << std::hex << x.d << "\n"; 
} 
5

你的第一个例子声明一个匿名的结构union

第二个示例声明了一个结构,其中包含union的声明,该声明是noop。例如。

typedef struct bitfield 
{ 
    unsigned int a:16; 
    unsigned int b:17; 
    union u 
    {  
     unsigned int c:4; 
     unsigned int d:32; 
    }; 
}bfield; 

int main(void) { 
    struct bitfield b; 
    b.c=2; 
} 

将失败,并

x.c:14:4: error: 'struct bitfield' has no member named 'c' 

编译器会发出警告它

x.c:9:6: warning: declaration does not declare anything 

所以,你的问题有位域,但与匿名联合没什么待办事项。

+2

...然后继续,你可能打算把u放在块之后,而不是之前,所以你会得到'union {uint c; uint d} u' –

+0

嗯,实际上它是匿名的'union'与'union'的声明,不仅是关于匿名'union'(或'structs')。 – Olaf

+0

@HaldeanBrown:这会让'u'不再是一个匿名的'union'。不知道这是OP想要的。 – Olaf