c++ - 结构填充值

标签 c++ struct

编辑 2:关于 XY 问题:

在二进制协议(protocol)中,我需要发送 8 个字节。这些字节可以包含 8 位或 16 位长的整数,也可以包含 1、2 或 3 位长的标志。

为了简化它,我更愿意使用结构:

struct MakeCoffeeCmd
{
    UINT8 sugar : 2;
    UINT8 milk : 1;
    UINT16 liters;
};

所以我可以这样使用它:

cmd.sugar = 1;
cmd.milk = 0;
cmd.liters = 42;

send(cmd);

问题是:糖、牛奶和升在 8 字节数组中有定义的位置,每个未使用的位必须设置为 1。

现在,我使用:

UINT8 cmd[8];
memset(&cmd, ~0, sizeof(cmd));

cmd[1] &= sugar << 4;
cmd[1] &= milk << 1;
*((UINT16*)(cmd + 3)) = liters;

send(cmd);

原始问题:

我想创建一个 8 字节长的结构。由于原因,我只关心第二个和第三个字节,所有其他字节必须设置为0xFF。

它应该是这样的:0xFF [Byte1] [Byte2] 0xFF 0xFF 0xFF 0xFF 0xFF

我试过这样,但它看起来太丑了。

struct mystruct
{
    mystruct() : should_be_ff(0xFF), should_also_be_ff(0xFF), sould_be_ff_too(0xFFFFFFFF) {}
    UINT8  should_be_ff;
    UINT16 important_values;
    UINT8  should_also_be_ff;
    UINT32 should_be_ff_too;
 }

我可以使用位字段进行填充,但我无法设置正确的值。

我更喜欢这样的东西:

struct mystruct
{
    0xFF;
    UINT16 important_values;
    0xFFFFFF;
}

有什么想法吗?

编辑 1:

我需要这个用于某些我无法更改的专有二进制协议(protocol)。这只是一个例子,还有更复杂的带有标志和位字段的结构。在数组中使用它们会很丑陋。

我修改了打包以(希望)消除填充错误。

最佳答案

I want to create an 8 byte long struct.

您的结构可能不是 8 个字节长。您将在成员之间以及可能在末尾进行填充。

没有标准方法可以保证结构的大小为 8 个字节。

如果正好需要 8 个字节,可以使用数组:

uint8_t arr[8];                    // exactly 8 bytes
memset(arr, ~0, sizeof arr);       // set all bits to 1 i.e. every byte to 0xff
uint16_t foo = 123u;               // some important 2-byte value
memcpy(arr + 1, &foo, sizeof foo); // copy the 2-byte value to the second and third index

请记住,字节顺序取决于架构的字节顺序。

关于编辑 2:

您当然可以使用类似的结构来表示您自己的应用程序中的协议(protocol)消息。但是要按照协议(protocol)发送,必须先将其转换为数组。必须逐场进行。由于填充和别名问题,转换无法跨平台正确执行。我建议使用 char 数组,因为 char 类型有关于别名的特殊规则,使它们更容易使用。

要将结构实例的未使用位设置为 1,最简单的解决方案可能是 memset:

MakeCoffeeCmd object;
memset(&object, ~0, sizeof object);

之后您可以设置使用的字段。然后将每个字段复制到数组中的正确位置。

关于c++ - 结构填充值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33671339/

相关文章:

c++ - 将 uint8_t 数组转换为 c++ 中的字符串以在一行中打印

c++ - 很好的替代Qt

c++ - 在 VS2008 中概述,C++,不工作

c++编译错误-体系结构x86_64的 undefined symbol

c++ - 在 Scheme 或 C++ 中实现 AKS 素数测试

从另一个文件调用节点

c - 使用 const 成员将结构转换为结构

c# - 列表+结构 : Object reference not set to an instance of an object

c - Swift/C 互操作,Swift 中的结构数据更改未在 C 中更新

c - 在指向结构的指针数组中混合指针的取消引用形式