【问题标题】:Padding of a struct in C with 3 bytes用 3 个字节填充 C 中的结构
【发布时间】:2020-11-07 11:24:35
【问题描述】:

假设我在 C 中有一个结构和变量,如下所示:

typedef struct {
  uint8_t x;
  uint8_t y;
  uint8_t z;
}my_type;

my_type a;
my_type a10[10];

用 C99 确定

  • sizeof(a) == 3? (不是 4 个或 8 个)
  • sizeof(a10) == 30? (而不是 40 或 80)

【问题讨论】:

  • 不,可能有填充,所以它可能而且可能会更大。
  • 根据 C 标准,可以在第一个成员(与整个结构的地址相同)之后的任何位置添加填充。虽然在这种情况下实现需要添加填充并没有特别的原因,但这样做是免费的。
  • @Fredrik:它可能不会更大。除非用户的特殊要求或某些特殊目的,否则没有正常的 C 实现向此结构添加填充。 C 标准允许实现添加填充,但普通 C 实现不允许 - 随机选择的 C 实现将赋予此结构更大尺寸的概率为零或接近零。
  • @EricPostpischil ARM 的每个“普通”编译器都绝对会将其填充到四个字节,大多数 x86 编译器也会如此,除非您特别要求将其打包。 32 位对齐是常态,而不是例外。

标签: c struct padding


【解决方案1】:

使用 C99 是否可以确定 sizeof(a) == 3?

此类型将用作 RGB888 帧缓冲区的颜色。所以相邻的 RGB 值之间不要有空格是很重要的。

typedef struct {
  uint8_t x;
  uint8_t y;
  uint8_t z;
}my_type;

没有。大小可能是 3 或 4(或理论上其他,但不太可能)


2 个解决方案:

  • 放弃可移植性,使用编译器指定代码打包结构。

  • struct 更改为 3 个 uint8_t 的数组并调整代码。

我推荐最后一个。

【讨论】:

    【解决方案2】:

    如 cmets 中所述,默认情况下可以添加填充。
    为避免这种情况,您可以将 __attribute__((packed)) 用于您的结构。
    这将告诉编译器尽可能紧凑地打包您的结构。
    看起来像这样:

    typedef struct {
      uint8_t x;
      uint8_t y;
      uint8_t z;
    } __attribute__((packed)) my_type;
    

    【讨论】:

    • 重要的缺失信息:这是一个 gcc 扩展,在这种情况下这不起作用,因为 gcc 已经生成了一个打包的结构,如果它确实有效果,它可能会影响性能。
    猜你喜欢
    • 2023-04-03
    • 2015-04-25
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    • 2014-10-12
    • 2011-10-21
    • 2013-10-29
    • 1970-01-01
    相关资源
    最近更新 更多