【问题标题】:memory layout for packed and unpacked structure打包和解包结构的内存布局
【发布时间】:2013-05-08 11:26:31
【问题描述】:

我定义了 2 个结构,如下所示。

#include<stdint.h>
typedef struct
{
   uint32_t a;
   uint8_t b;
   uint8_t pad[3]; //padding here is added intentionally. 
   uint32_t c;
}A;

typedef struct
{
   uint32_t a;
   uint8_t b;
   uint8_t pad[3];
   uint32_t c;
}__attribute__((__packed__)) B;

这两个结构是否保证在所有硬件平台上具有完全相同的内存布局?可以假设编译器总是gcc。

【问题讨论】:

    标签: c memory struct


    【解决方案1】:

    没有。在这个结构的解压版本中仍然可能有填充。即使今天没有这样的实现,未来也可能会有一种架构——当所有类型与可被 128 整除的偏移量对齐时,它的所有类型都是最佳的,并且解压版本中的任何成员都可以跟随在在这样的系统上填充 120 位和 96 位。编译器可能会利用这一点。 Stackoverflow 是永恒的。

    【讨论】:

      【解决方案2】:

      答案是“可能”,但不是“保证”,因为所有架构的覆盖范围非常广泛。我可以设想一些具有内存架构的系统,其读/写性能更愿意将读写保持在大于 uint8_t 的边界上。

      请注意,打包时,编译器将使用对于特定架构通常不是最佳的读/写代码,但在访问结构成员方面是正确的。

      【讨论】:

      • 没有。这意味着uint8_t 要么有填充(它不能有),要么是最小的可寻址类型(这意味着CHAR_BIT == 8)。
      • @undefinedbehaviour - 您显然从未在 CHAR_BIT == 16 的定点 DSP 上工作过。您仍然可以声明 uint8_t 或 int8_t 但除非您指定,否则它会在数组或结构的一部分时被填充结构的打包属性。
      • 7.20.1.1 精确宽度整数类型 1 typedef 名称 intN_t 指定宽度为 N、无填充位和二进制补码表示。因此, int8_t 表示这种宽度正好为 8 位的有符号整数类型。 2 typedef 名称 uintN_t 指定一个宽度为 N 且没有填充位的无符号整数类型。因此,uint24_t 表示这样一种无符号整数类型,其宽度正好为 24 位。
      • 3 这些类型是可选的。但是,如果实现提供了宽度为 8、16、32 或 64 位的整数类型,没有填充位,并且(对于有符号类型)具有二进制补码表示,则它应定义相应的 typedef 名称。
      • 从 C 标准中可以看出,用于 ​​DSP 的任何编译器都不是有效的 C 编译器。那,或者你错了。
      猜你喜欢
      • 2015-04-13
      • 2022-07-27
      • 1970-01-01
      • 2016-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 2011-02-14
      相关资源
      最近更新 更多