我偶然发现了一些代码(它在一个来自微芯片的库中),它有一个联盟。
一切都很好,直到我看到它把价值分配给不同的工会成员。我当时的想法是“他们在写同一个地方.”然后我决定做个测试。以我所理解的每一种方法来衡量,这个联合应该是一个字节(8位)。但这不是..。它是4个字节。
#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位。
引起我注意并让我调查的代码是:
STAT.BC9 = 0;
STAT.BC8 = 0;
STAT.Val |= byteToSend;将第三行合并到第一和第二行的值中。
所以我想测试它,它是4个字节,而不是一个字节。我甚至在几个不同的编译器中测试了它(因此在MS Visual C中使用了#实用化)。
每个成员正好是8位,最后两个结构重叠,将PID值放置在相同的内存位置。然而,这是4个字节,每次我使用编译器来计算它。
在工会中添加结构的行为中有什么东西吗?
任何解释都不胜感激。
发布于 2021-09-13 13:46:57
虽然没有在C标准中显式指定,但位字段通常会占用与其声明的基本类型相对应的单元。
在这种情况下,所有的位字段都声明为unsigned。这种类型在您的系统中可能是4个字节,因此位字段占据了该类型的一个单元。
如果将字段类型更改为unsigned char或uint8_t,则它们只占一个字节。请注意,这假设您的编译器允许将这些类型用于位字段,尽管大多数是这样做的。
发布于 2021-09-13 13:47:41
C有隐式的概念。因此,unsigned将声明一个unsigned int。但越来越奇怪了。如果您只使用const或static/auto,情况也是如此。
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位。
至少应该有这个尺寸。没有什么能阻止它变得更大。
发布于 2021-09-13 14:05:37
它不会编译,因为在匿名structures.
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)。
https://stackoverflow.com/questions/69163749
复制相似问题