3

我想将枚举定义为小于一个字节,同时保持类型安全。

将枚举定义为:

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;};
   }; 
};
4

4 回答 4

5

根据标准定义,类型sizeof必须至少为 1 个字节。这是内存的最小可寻址单元。

您提到的位域的功能允许将结构的成员定义为具有较小的大小,但结构本身可能不是因为

  • 它也必须至少有 1 个字节
  • 对齐考虑可能需要更大

此外,您可能不会获取位域成员的地址,因为如上所述,一个字节是内存的最小可寻址单元(您已经可以通过sizeof实际返回字节数而不是位来看到这一点,所以如果您期望小于CHAR_BIT位,sizeof甚至无法表达)。

于 2013-06-11T21:02:43.183 回答
1

不。C++ 将“char”定义为平台的最小可寻址内存单元。您无法寻址 2 位。

于 2013-06-11T21:01:25.837 回答
1

位域只有使用相同的底层类型才能共享空间。并且任何未使用的位实际上都未使用;如果位域中的位总和unsigned int为 3 位,则总共仍需要 4 个字节。由于两个枚举都有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

于 2013-06-11T21:30:20.513 回答
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. 您如何/测量什么?

编辑:实时链接

您是否正在做类似在结构中使用指针作为下一件事情的事情?在这种情况下,您将拥有 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。不过,我不确定工会和位包装如何协同工作,所以我没有更多帮助。

于 2013-06-11T21:00:27.230 回答