6

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__));
4

3 回答 3

9

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

GCC 10.2 的当前文档明确指出,打包结构的成员的内部布局未打包(因为外部结构上的属性;当然,它可以根据自己的定义进行打包)。

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

于 2021-02-26T16:09:27.017 回答
1

在实践中它没有:见https://godbolt.org/z/4YMaz8。注意.zero 2成员的两个成员之间的填充unpackedStruct

手册中明确提到了这种情况,示例与您的示例几乎相同:

在下面的示例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必须适用于一个type,你不能有一些该类型的对象被打包,而另一些则没有。

于 2021-02-26T16:04:35.740 回答
0

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

于 2021-02-26T16:17:42.083 回答