【问题标题】:Are unpacked struct in packed struct automatically packed?打包结构中的未打包结构是否自动打包?
【发布时间】:2021-05-29 00:23:28
【问题描述】:

packed struct 中的 unpacked struct 会被 GCC 自动打包吗?

换句话说,__packed__ 属性会自动传播到嵌套结构吗?

也就是说:

struct unpackedStruct{
    int16_t field1;
    int32_t field2;
    // etc...
}

struct packedStruct{
    int16_t field1;
    struct unpackedStruct struct1; // <-- Is this struct packed?
    // etc...
} __attribute__((__packed__));

【问题讨论】:

  • 最好不要 - 否则将该成员传递给任何其他期望普通 unpackedStruct 的代码将惨遭失败。无论如何,你可以测试它。
  • @NateEldredge 另外,从一个人直接分配到另一个人是行不通的。
  • 这应该很容易使用编译器进行检查。

标签: c++ c gcc struct packed


【解决方案1】:

不,内部结构没有打包。在this Godbolt example中,我们可以看到struct foo没有打包在struct bar里面,struct bar里面有packed属性;创建的struct bar 对象在其struct foo 成员内包含三个字节的填充(可见为.zero 3),位于struct foo 成员ci 之间。

Current documentation for GCC 10.2 明确表示压缩结构成员的内部布局未压缩(因为外部结构上的属性;当然,它可以根据自己的定义进行压缩)。

(在older documentation中表示将packed应用于结构等同于将其应用于其成员,这意味着将packed应用于作为成员的“变量”的效果,在@987654324中描述@. 当packed 应用于结构成员时,它会导致该成员的对齐要求为一个字节。也就是说,它消除了先前成员与该成员之间的填充,因为不需要填充来使其对齐。它不会改变成员本身的表示。如果该成员是一个解压缩结构,它在内部仍然是一个解压缩结构。)

【讨论】:

    【解决方案2】:

    不 - 打包不是递归的,因此每个成员都需要自己打包。

    【讨论】:

      【解决方案3】:

      实际上它没有:请参阅https://godbolt.org/z/4YMaz8。注意unpackedStruct 成员的两个成员之间的填充.zero 2

      manual 中明确提到了这种情况,并举了一个与您几乎相同的示例:

      在下面的示例中,struct my_packed_struct 的成员紧密地打包在一起,但其 s 成员的内部布局没有打包——为此,struct my_unpacked_struct 需要打包也是。

      struct my_unpacked_struct
       {
          char c;
          int i;
       };
      
      struct __attribute__ ((__packed__)) my_packed_struct
        {
           char c;
           int  i;
           struct my_unpacked_struct s;
        };
      

      基本思想是给定类型的每个对象都应该具有相同的布局,以便在该类型上运行的代码将适用于该类型的每个对象。所以packed 必须适用于一个类型,你不能有一些该类型的对象被打包而另一些则没有。

      【讨论】:

      • 我认为barfoo 代码无论如何都必须中断,因为&amp;p.struct1 可能不会像struct my_unpacked_struct 那样对齐。 Clang 产生“错误:获取类或结构 'my_packed_struct' 的打包成员 's' 的地址可能导致未对齐的指针值 [-Werror,-Waddress-of-packed-member]”,而 GCC 10.2 保持沉默。
      • 好吧,假设它会更糟——在没有严格对齐要求的平台上,它可能会工作。或者您可以想象将__attribute__((aligned(1))) 应用于struct unpackedStruct
      • @EricPostpischil:但我还是会把它拿出来。
      • 我会保留它,但要单独提及对齐问题。如果struct foo 成员真正被打包,它根本不能用作struct foo。但由于它没有打包,只是未对齐,因此实际上有两种类型,struct foostruct foo __attribute__((__aligned__(1)))。您可以一对一地memcpy
      猜你喜欢
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 2023-04-02
      • 2013-01-24
      相关资源
      最近更新 更多