我需要处理以下形式的一些数据:
typedef struct{
unsigned n1 : 12;
unsigned n2 : 12;
unsigned n3 : 12;
unsigned n4 : 1;
unsigned n5 : 35;
} data;
我确保它们总共计数到 9 个字节。
但他们没有.. 将该结构的 9 个字节写入文件并将其读回并不会恢复所有数据,而是sizeof(data)
返回 16。
这里有什么问题?
我需要处理以下形式的一些数据:
typedef struct{
unsigned n1 : 12;
unsigned n2 : 12;
unsigned n3 : 12;
unsigned n4 : 1;
unsigned n5 : 35;
} data;
我确保它们总共计数到 9 个字节。
但他们没有.. 将该结构的 9 个字节写入文件并将其读回并不会恢复所有数据,而是sizeof(data)
返回 16。
这里有什么问题?
问题是出于效率原因,编译器正在添加一些填充。
可以覆盖此行为。
有关如何使用 gcc 执行此操作,请参阅在 GCC 中强制对齐
有关如何使用 Visual C++ 执行此操作,请参阅:在 Visual C++ 中强制对齐
您的结构长 9 个字节。编译器将其填充到 16 字节以更加缓存友好。这可以使用编译器特定的指令/关键字来关闭(我一般不推荐)。请参阅数据结构对齐。
您可以使用 gcc 特定的强制对齐:
typedef struct{
unsigned n1 : 12;
unsigned n2 : 12;
unsigned n3 : 12;
unsigned n4 : 1;
unsigned n5 : 35;
} data __attribute__((__packed__));
阅读: http: //gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Type-Attributes.html
这在 36 位计算机上运行得非常好。你忘了告诉我们这是不是你得到的……
在更常见的 32 位机器上,使用 9 字节对齐将很难实现。如果您创建这些结构的数组,您将需要不同的代码来访问地址模 0 和地址模 9 的对象中的字段。
前三个字段的 12 位必须从不同unsigned
的 s 中收集,并且根据地址的不同而不同。
其他答案中的打包指令不太可能在这里工作,除非您有带位寻址的硬件(或 36 位 CPU)。