我想在保持类型安全的同时将枚举定义为小于一个字节。
将枚举定义为:
enum MyEnum : unsigned char
{
i ,j, k, w
};
我可以把它缩小到一个字节,但是我想让它只使用2位,因为我最多只有4个值。可以这样做吗?
在我使用枚举的结构中,以下内容不起作用
struct MyStruct
{
MyEnum mEnum : 2; // This will be 4 bytes in size
};
谢谢!
更新
问题来自这种情况:
enum MyEnum : unsigned char
{
i ,j, k, w
};
struct MyStruct
{
union
{
signed int mXa:3;
unsigned int mXb:3;
};
union
{
signed int mYa:3;
unsigned int mYb:3;
};
MyEnum mEnum:2;
};
sizeof(MyStruct)显示9个字节。理想情况下,我希望结构的大小为1个字节。
已实施解决方案的更新:
此结构是一个字节,提供相同的功能和类型安全性:
enum MyEnum :unsigned char
{
i,j,k,w
};
struct MyStruct
{
union
{
struct { MyEnum mEnum:2; char mXa:3; char mXb:3;};
struct { MyEnum mEnum:2; unsigned char mYa:3; unsigned char mYb:3;};
};
};
答案 0 :(得分:4)
根据标准定义,类型sizeof
必须至少为1个字节。这是最小的可寻址内存单元。
您提到的位域的功能允许定义结构的成员以具有更小的尺寸,但结构本身可能不是因为
另外你可能不会获取位域成员的地址,因为如上所述,一个字节是内存的最小可寻址单位(你已经可以看到sizeof
实际上返回的是字节数,而不是位数,因此,如果您预计会少于CHAR_BIT
位,sizeof
甚至无法表达它。)
答案 1 :(得分:1)
没有。 C ++将“char”定义为平台的最小可寻址内存单元。你不能解决2位。
答案 2 :(得分:1)
位域只有在使用相同的底层类型时才能共享空间。任何未使用的位实际上都是未使用的;如果unsigned int
位域中的位总和为3位,则仍需要4个字节 total 。由于两个枚举都有unsigned int
个成员,因此它们都是4个字节,但由于它们是位域,因此它们的对齐方式为1。所以第一个enum
是4个字节,第二个是4个字节,那么MyEnum
是1个字节。由于所有这些都具有一个对齐,因此不需要填充。
不幸的是,union
根本不适用于位域。位域仅适用于整数类型。在没有认真重新设计的情况下,我能获得的最多数据是3个字节:http://coliru.stacked-crooked.com/view?id=c6ad03c93d7893ca2095fabc7f72ca48-e54ee7a04e4b807da0930236d4cc94dc
enum MyEnum : unsigned char
{
i ,j, k, w
};
union MyUnion
{
signed char ma:3; //char to save memory
unsigned char mb:3;
};
struct MyStruct
{
MyUnion X;
MyUnion Y;
MyEnum mEnum;
}; //this structure is three bytes
在完整的重新设计类别中,您有:http://coliru.stacked-crooked.com/view?id=58269eef03981e5c219bf86167972906-e54ee7a04e4b807da0930236d4cc94dc
答案 3 :(得分:0)
比特包装'适合我'
#include <iostream>
enum MyEnum : unsigned char
{
i ,j, k, w
};
struct MyStruct
{
MyEnum mEnum : 2;
unsigned char val : 6;
};
int main()
{
std::cout << sizeof(MyStruct);
}
打印出来1.你是如何/你在测量什么?
修改:Live link
你是否正在做一个像指针作为结构中的下一个东西?在这种情况下,你将有30位死区,因为指针必须在大多数32位系统上对齐4字节。
编辑:使用您更新的示例,其中的工会正在破坏您
enum MyEnum : unsigned char
{
i ,j, k, w
};
struct MyStruct
{
unsigned char mXb:3;
unsigned char mYb:3;
MyEnum mEnum:2;
};
大小1.我不确定工会和比特包装是如何协同工作的,所以我没有更多的帮助。