数据结构对齐

mam*_*don 0 c++ linux networking attributes gcc

所以,我正在编写一些数据包结构(以太网,IP等),并注意到其中一些后跟属性((packed)),这阻止了gcc编译器尝试向它们添加填充.这是有道理的,因为这些结构应该在线上.

但是,我算了几句话:

struct ether_header
{
  u_int8_t  ether_dhost[ETH_ALEN];  /* destination eth addr */
  u_int8_t  ether_shost[ETH_ALEN];  /* source ether addr    */
  u_int16_t ether_type;             /* packet type ID field */
} __attribute__ ((packed));
Run Code Online (Sandbox Code Playgroud)

这是从站点复制的,但我的代码也使用了2 uint8_t和1 uint16_t.这总计最多两个字(4个字节).

根据源,系统优选根据4,8或甚至16位的倍数对齐结构.所以,我不明白为什么属性((打包))是必要的,因为afaik这不应该被打包.

另外,为什么双支架((打包))为什么不使用一对呢?

Ada*_*eld 5

如果你的结构已经是正确大小的倍数,那么不是,这__attribute__((packed))不是绝对必要的,但它仍然是一个好主意,以防你的结构大小因任何原因而发生变化.如果您添加/删除字段或更改ETH_ALEN,您仍然需要__attribute__((packed)).

我认为需要使用双括号才能使代码与非gcc编译器兼容.通过使用它们,您可以这样做:

#define __attribute__(x)
Run Code Online (Sandbox Code Playgroud)

然后,您指定的所有属性都将消失.额外的括号意味着只有一个参数传递给宏(而不是一个或多个),无论您指定了多少属性,并且您的编译器不需要支持可变参数宏.