我目前正试图找出一种优雅而方便的方法,在64位边界内存储4个14位值和1个8位值。
像这样的:

typedef struct my64bit{
    unsigned data1 : 14;
    unsigned data2 : 14;
    unsigned data3 : 14;
    unsigned data4 : 14;
    unsigned other : 8;
}tmy64Bit;

稍后我不想创建这些“容器”的数组
tmy64Bit myArray[1000];

所以我有一个指向1000x64位内存的指针“myarray”
这个数组通过tcp发送到一个嵌入式linux socfpga系统,在那里它应该被复制到一个特定的内存中(直接从fpga访问)。
我的问题是上面的代码没有创建64位类型
sizeof(tmy64Bit)

返回12,因此分配12个字节而不是8个字节
用数据填充结构并观察内存(在我的64位Linux系统上)返回
tmy64Bit test;
memset(&test,0,sizeof(tmy64Bit));
test.data1 = 0x3fff;
...
test.other = 0xAA;

Memory View:
after d1 written = 0xFF3F0000 00000000 00000000
after d2 written = 0xFFFFFF0F 00000000 00000000
after d3 written = 0xFFFFFF0F FF3F0000 00000000
after d4 written = 0xFFFFFF0F FFFFFF0F 00000000
after o  written = 0xFFFFFF0F FFFFFF0F AA000000

因此,前2个14位变量被正确存储,但填充会填满最后半个字节,最后一个字节需要存储在一个新的64位单元中
另一个办法是
typedef struct my2nd64Bit{
 uint8_t data[7];
 uint8_t other;
}tmy2nd64Bit;

其中
sizeof(tmy2nd64Bit)

返回8(这是预期的)
这会生成正确的填充结构,但是存储14位总是需要大量的位移位和掩蔽。

最佳答案

这就是你想要的:

typedef struct my64bit{
    uint64_t data1 : 14;
    uint64_t data2 : 14;
    uint64_t data3 : 14;
    uint64_t data4 : 14;
    uint64_t other : 8;
}tmy64Bit;

unsigned表示unsigned int,在大多数系统上,此类型为32位。这将导致填充,因为不允许单个字段跨越32位边界。在这种情况下,使用64位成员类型不会添加填充(您不会跨越任何64位边界)。
对于任何关于位字段的问题,您需要记住,大多数位字段机制都是由实现定义的,这意味着如果您想使用它,您应该检查您是否真正得到了您想要的。另外,如果您计划使用另一个编译器,请检查其行为是否相同(通常是相同的,但可能不在特殊的平台上)。如果正确检查,这是可以安全使用的(不是未定义的行为),但是您可能希望使用更可移植的方式,例如使用位操作。

关于c - c中的自定义数据类型:64位“容器”中的4x14位+ 1x8位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35724387/

10-09 01:32