首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个联盟像个结构体?

为什么这个联盟像个结构体?
EN

Stack Overflow用户
提问于 2021-09-13 13:41:50
回答 4查看 432关注 0票数 7

我偶然发现了一些代码(它在一个来自微芯片的库中),它有一个联盟。

一切都很好,直到我看到它把价值分配给不同的工会成员。我当时的想法是“他们在写同一个地方.”然后我决定做个测试。以我所理解的每一种方法来衡量,这个联合应该是一个字节(8位)。但这不是..。它是4个字节。

代码语言:javascript
复制
#pragma pack(1)
typedef union _STATUS
{
    BYTE Val;
    struct {
        unsigned BC8 : 1;
        unsigned BC9 : 1;
        unsigned BSTALL : 1;
        unsigned DTSEN : 1; 
        unsigned INCDIS : 1;
        unsigned KEN : 1;   
        unsigned DTS : 1;   
        unsigned UOWN : 1;  
    };
    struct {
        unsigned BC8 : 1;
        unsigned BC9 : 1;
        unsigned PID0 : 1;
        unsigned PID1 : 1;
        unsigned PID2 : 1;
        unsigned PID3 : 1;
        unsigned : 1;
        unsigned UOWN : 1;
    };
    struct {
        unsigned : 2;
        unsigned PID : 4; 
        unsigned : 2;
    };
} STATUS;
void PrintIt() {
    printf("Size of UNION is %d \n", sizeof(STATUS));
}

它应该是任何成员中最大的,每个成员只有8位。

引起我注意并让我调查的代码是:

代码语言:javascript
复制
STAT.BC9 = 0;
STAT.BC8 = 0;
STAT.Val |= byteToSend;

将第三行合并到第一和第二行的值中。

所以我想测试它,它是4个字节,而不是一个字节。我甚至在几个不同的编译器中测试了它(因此在MS Visual C中使用了#实用化)。

每个成员正好是8位,最后两个结构重叠,将PID值放置在相同的内存位置。然而,这是4个字节,每次我使用编译器来计算它。

在工会中添加结构的行为中有什么东西吗?

任何解释都不胜感激。

EN

回答 4

Stack Overflow用户

发布于 2021-09-13 13:46:57

虽然没有在C标准中显式指定,但位字段通常会占用与其声明的基本类型相对应的单元。

在这种情况下,所有的位字段都声明为unsigned。这种类型在您的系统中可能是4个字节,因此位字段占据了该类型的一个单元。

如果将字段类型更改为unsigned charuint8_t,则它们只占一个字节。请注意,这假设您的编译器允许将这些类型用于位字段,尽管大多数是这样做的。

票数 6
EN

Stack Overflow用户

发布于 2021-09-13 13:47:41

C有隐式的概念。因此,unsigned将声明一个unsigned int。但越来越奇怪了。如果您只使用conststatic/auto,情况也是如此。

代码语言:javascript
复制
const x = 5; // Declares a const int variable
static x;    // Declares a static int variable
const static unsigned x = 5; // Declares a const static unsigned int variable

你想要的是一个unsigned char

应该是所有成员中最大的,每个成员只有8位。

至少应该有这个尺寸。没有什么能阻止它变得更大。

票数 5
EN

Stack Overflow用户

发布于 2021-09-13 14:05:37

它不会编译,因为在匿名structures.

  • You中有重复的成员名,如果您对位字段使用8位类型,则确实需要打包。

代码语言:javascript
复制
typedef union 
{
    unsigned char Val;
    struct {
        unsigned char BC8 : 1;
        unsigned char BC9 : 1;
        unsigned char BSTALL : 1;
        unsigned char DTSEN : 1; 
        unsigned char INCDIS : 1;
        unsigned char KEN : 1;   
        unsigned char DTS : 1;   
        unsigned char UOWN : 1;  
    };
    struct {
        unsigned char BC81 : 1;
        unsigned char BC91 : 1;
        unsigned char PID0 : 1;
        unsigned char PID1 : 1;
        unsigned char PID2 : 1;
        unsigned char PID3 : 1;
        unsigned char : 1;
        unsigned char UOWN1 : 1;
    };
    struct {
        unsigned char : 2;
        unsigned char PID : 4; 
        unsigned char : 2;
    };
} STATUS;

int main(void) {
    printf("Size of UNION is %d \n", (int)sizeof(STATUS));
}

https://godbolt.org/z/zsfhnGeWd

请记住,一些编译器将打包到您指定的类型(例如chibicc)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69163749

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档