c - 是否应该将所有预期从二进制文件中读取的结构标记为已打包?

标签 c data-structures memory io

我知道某些结构可能会或可能不会在元素之间添加填充。

我当前的项目正在从/dev/input 文件中读取输入。这些文件的二进制布局在 <linux/input.h> 中定义:

struct input_event {
    struct timeval time;
    __u16 type;
    __u16 code;
    __s32 value;
};

我想知道这个结构是不是没有用打包属性标记。这意味着/dev/input 文件(逐位打包)不能保证与结构匹配相同的包。因此逻辑

struct input_event event;
read(fd, &event, sizeof(event));

未定义为适用于所有架构。

我的逻辑有谬误吗?或者假设某些东西不会被打包是否安全?

最佳答案

布局打包

在当前情况下,您是安全的。您的 struct input_event 已准备就绪。

struct timeval time;  /* 8 bytes */
__u16 type;           /* 2 bytes */
__u16 code;           /* 2 bytes */
__s32 value;          /* 4 bytes */

这意味着,成员形成干净的 32 位 block ,因此不需要填充。这article解释结构成员(尤其是字符)的大小及其布局如何影响填充,从而影响结构的最终大小。

预处理器打包

乍一看,通过预处理器打包结构似乎是一个很好的解决方案。仔细观察,会发现一些缺点,其中一个会在您关心的地方打击您(另请参见 #pragma pack effect)

性能

填充确保您的结构成员无需在内存块内部搜索即可访问(分别为 32 位机器上的 4 字节 block 和 64 位机器上的 8 字节 block )。因此,打包此类结构会导致成员跨越多个内存块,因此需要机器搜索它们。

不同的平台(Archs、编译器)

预处理器指令在很大程度上是特定于供应商和体系结构的。因此,使用它们会导致代码的可移植性较差或在最坏的情况下不可移植。

结论

作为此 article 的作者(上面已经提到)状态,甚至 NTP 直接从网络读取数据到结构中。 因此,仔细布置您的结构并可能手动填充它们可能是最安全且最便携的解决方案。

关于c - 是否应该将所有预期从二进制文件中读取的结构标记为已打包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42115403/

相关文章:

algorithm - 需要以下分布的算法

Tomcat 服务器 JAVA 空闲内存未返回给操作系统

c - 使 C 浮点文字 float (而不是 double )

c - 这些局部变量地址背后的基本原理是什么?

java - 使用哪种数据结构?索引数据结构乱序插入

c++ - 仅释放分配给 "operator new"的一部分内存

c - 按字典顺序返回内存字符对用户输入进行排序?

python - 将 ctypes 与 typedef 一起使用

c - 调试错误选择排序

java - 二叉树遍历不起作用