【问题标题】:Datastructure alignment数据结构对齐
【发布时间】:2009-11-05 02:56:18
【问题描述】:

所以,我正在编写一些数据包结构(以太网、IP 等),并注意到其中一些后跟 attribute((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));

这是从一个站点复制的,但我的代码也使用了 2 个 uint8_t 和 1 个 uint16_t。这加起来最多两个字(4 个字节)。

根据来源,系统更喜欢根据 4,8 甚至 16 位的倍数对齐结构。所以,我不明白为什么 attribute((packed)) 是必要的,因为 afaik 这不应该被打包。

还有,为什么双括号 ((packed)) 为什么不用一对呢?

【问题讨论】:

    标签: c++ linux gcc networking attributes


    【解决方案1】:

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

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

    #define __attribute__(x)
    

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

    【讨论】:

    • 我忘记了 uint8_t 是数组;愚蠢的我,但很好地呼吁改变计划。
    【解决方案2】:

    虽然您的系统可能更喜欢某种特定的对齐方式,但其他系统可能不会。就算__attribute__((packed))没有效果,也算是一种偏执吧。

    至于为什么是双括号,这个GCC特有的扩展需要双括号。单括号会报错。

    【讨论】:

      【解决方案3】:
      在win32中,你可以这样做: #pragma pack(push) //保存当前状态 #pragma pack(4)//设置跟随为4对齐 结构测试 { 字符 m1; 双 m4; 国际立方米; }; #pragma pack(pop) //恢复

      【讨论】:

        【解决方案4】:

        packed 指的是结构内部的填充/对齐,而不是结构的对齐。比如

        struct {
          char x;
          int y;
        }
        

        大多数编译器会在偏移量 4 处分配 y,除非您将结构声明为打包(在这种情况下,y 将在偏移量 1 处分配)。

        【讨论】:

        • 在这样的结构上使用 packed 是一个非常糟糕的主意,因为对 y 的访问会在许多平台上陷入困境。
        • 更一般地说,依赖一个 C 结构来表示一个独立于平台的数据布局是自找麻烦。打包只是用一个麻烦换另一个麻烦。
        【解决方案5】:

        对于这个结构,即使 ETH_ALEN 是一个奇数,你也有两个,所以 uint16 变量必须在两个或零字节偏移处,并且打包不会做任何事情。依赖于打包对于可移植性来说是个坏主意,因为打包机制是不可移植的,如果你使用它们,你可能不得不在你的成员变量中进行字节复制,以避免在这很重要的平台上出现错位异常。

        【讨论】:

          猜你喜欢
          • 2013-06-03
          • 2023-03-23
          • 1970-01-01
          • 1970-01-01
          • 2012-06-05
          • 2019-02-08
          • 1970-01-01
          • 2023-03-16
          • 2013-10-22
          相关资源
          最近更新 更多