当前位置: 首页 > 知识库问答 >
问题:

32 位和 64 位体系结构中的结构填充差异,带uint64_t

籍英叡
2023-03-14

我有两个结构,如下所述。注释指定数据成员的大小和编译器将扩充的填充值。

#include <stdio.h>
#include <stdint.h>


typedef struct peer_msg_hdr
{
  char type;            /**< 1 */
                        /**< pad[3] */
  uint32_t id;          /**< 4 */
  uint64_t timestamp;   /**< 8 */
} PEER_MSG_HDR;         /**< 16 */

typedef struct peer_msg 
{
  PEER_MSG_HDR hdr;      /**< 16 */
  uint16_t listen_port;  /**< 2 */
                         /**< pad[2] */

  uint32_t num_nodes;    /**< 4 */
  uint32_t num_proc;     /**< 4 */
} PEER_MSG;


int main()
{
  printf("%lu\n", sizeof(PEER_MSG));
  return 0;
}

现在在一台x86_64主机中,首先我计算PEER_MSG的大小。原来是32岁。接下来,如果我在 gcc 中使用 -m32 选项计算大小,则大小为 28。

这两者之间的差异出现在最后一个数据成员 num_proc 之后的填充中。在 -m32 选项编译的情况下,没有填充。但是如果没有 -m32 选项,则有一个 4 个字节的填充(将整个结构对齐为 8 个字节,因为最宽的数据成员大小为 8 个字节(uint64_t 时间戳))。

我的问题是:使用 -m32 选项,uint64_t 的大小仍然是 8 个字节,但结构PEER_MSG的对齐方式是 4 个字节,这与填充的一般规则相矛盾(结构对齐方式应等于其最宽数据成员的对齐方式)。那么这里使用 -m32 选项填充的编译器规则是什么?

共有2个答案

常雅珺
2023-03-14

我的问题是:使用 -m32 选项,uint64_t的大小仍然是 8 个字节,但结构PEER_MSG的对齐方式是 4 个字节,

  • 这是完全正确的。在 32 位系统中,uint64_t的大小也是 8 字节。结构藻是基于字大小 4 字节完成的。

您的结构对齐点应等于其最宽数据成员的对齐是错误的。

  • 结构藻类基于体系结构的字大小(不是最广泛的数据成员)。在 32 位架构中,字大小为 4 字节,而在 64 位架构中,字大小为 8 字节。
鄂伟兆
2023-03-14

在 32 位机器上,处理字大小为 4 个字节,因此结构根据 28 字节的大小对齐,这就是为什么你得到 PEER_MSG 的大小为 28 字节。在 64 字节的系统上,由于处理字的大小为 8 个字节,因此PEER_MSG的大小为 32 个字节。

当您指定 -m32 选项时,编译器将假定最终可执行文件将在 32 字节系统上运行,因此会适当地进行填充。

 类似资料:
  • 问题内容: 我们已经继承了一个ant构建文件,但现在需要同时部署到32位和64位系统。 非Java位是通过GNUMakefiles完成的,我们只调用“ uname”来获取信息。有没有类似或什至更简单的方法来模仿蚂蚁呢? 问题答案: 您可以使用$ {os.arch}从ant 获得Java系统属性(http://java.sun.com/javase/6/docs/api/java/lang/Syst

  • 问题内容: 您如何使用Java确定Windows的32位或64位体系结构? 问题答案: 请注意,该属性仅会为您提供 JRE 的体系结构,而不是基础os 的体系结构。 如果在64位系统上安装32位jre,将返回 为了真正确定基础架构,您将需要编写一些本机代码。有关更多信息,请参见此帖子(以及示例本地代码的链接)。

  • 我试图比较Peter Cordes在回答“将CPU寄存器中的所有位设置为1”的问题时提到的方法。 因此,我编写了一个基准测试,将所有13个寄存器设置为除、和之外的所有位1。 代码如下所示<代码>乘以32 nop用于避免DSB和LSD影响。 我测试了他提到的以下方法,以及这里的完整代码 为了使这个问题更简洁,我将使用替换下表中的。 下表显示,从组1到组3,当使用64位寄存器时,每个循环多1个周期。

  • 问题内容: 我已经使用Java一段时间了,而我典型的设置新开发机的习惯要求从Oracle站点下载并安装最新的JDK。 今天这引发了一个不寻常的问题, 回想起来,我已经安装了之前的两个版本,并且很高兴将普通的工具链插入(Eclipse)。在我的日常编程中,我不会回想起曾经因为使用64位JRE(或为此目的而针对64位JRE)而不得不以其他方式进行更改或思考的事情。 根据我对64位和32位的理解- 确实

  • 问题内容: 我正在创建一个非常简单的应用程序,该应用程序可以读取和显示文本文件并进行搜索。 我问自己是否有兴趣向用户提出32位和64位版本。 区别仅在于使用64位版本访问更多的内存堆大小,还是还有其他兴趣? 32位编译程序是否可以在64位JVM上运行(我认为是) 问题答案: 任何 程序的32位和64位版本之间的唯一区别是机器字的大小,可寻址内存的数量以及所使用的操作系统ABI。对于Java,语言规

  • 本文向大家介绍查看Linux系统是32位还是64位的方法总结,包括了查看Linux系统是32位还是64位的方法总结的使用技巧和注意事项,需要的朋友参考一下 方法1:getconf LONG_BIT 查看 如下例子所示: 32位Linux系统显示32, 64位Linux系统显示64。最简单、快捷的方法。 32 64  方法2:uname命令查看 如下例子所示,x86_64表示64位系统, i686

  • Ceph 独一无二地用统一的系统提供了对象、块、和文件存储功能,它可靠性高、管理简便、并且是自由软件。 Ceph 的强大足以改变贵公司的 IT 基础架构、和管理海量数据的能力。Ceph 可提供极大的伸缩性——供成千用户访问 PB 乃至 EB 级的数据。 Ceph 节点以普通硬件和智能守护进程作为支撑点, Ceph 存储集群组织起了大量节点,它们之间靠相互通讯来复制数据、并动态地重分布数据。 Cep

  • 我们有一个单片应用程序,我们现在正在使用容器将其转换为微服务架构。 每种方法的利弊是什么?根据微服务最佳实践,什么是最佳方法?*