【问题标题】:No Memory Alignment with GCC没有与 GCC 的内存对齐
【发布时间】:2013-08-20 17:36:58
【问题描述】:

我正在处理一些数据包数据。我创建了结构来保存数据包数据。这些结构是由 python 为特定的网络协议生成的。

问题在于,由于编译器会对齐结构,当我通过网络协议发送数据时,消息最终会比我想要的长。这会导致其他设备无法识别该命令。

有没有人知道可以解决这个问题,以便我的打包程序与结构的大小完全相同,或者有什么方法可以关闭内存对齐?

【问题讨论】:

    标签: c gcc compiler-construction compiler-optimization memory-alignment


    【解决方案1】:

    在 GCC 中,您可以使用__attribute__((packed))。现在 GCC 也支持#pragma pack

    1. attribute documentation
    2. #pragma pack documentation

    例子:

    1. attribute方法:

      #include <stdio.h>
      
      struct packed
      {
          char a;
          int b;
      } __attribute__((packed));
      
      struct not_packed
      {
          char a;
          int b;
      };
      
      int main(void)
      {
          printf("Packed:     %zu\n", sizeof(struct packed));
          printf("Not Packed: %zu\n", sizeof(struct not_packed));
          return 0;
      }
      

      输出:

      $ make example && ./example
      cc     example.c   -o example
      Packed:     5
      Not Packed: 8
      
    2. pragma pack方法:

      #include <stdio.h>
      
      #pragma pack(1)
      struct packed
      {
          char a;
          int b;
      };
      #pragma pack()
      
      struct not_packed
      {
          char a;
          int b;
      };
      
      int main(void)
      {
          printf("Packed:     %zu\n", sizeof(struct packed));
          printf("Not Packed: %zu\n", sizeof(struct not_packed));
          return 0;
      }
      

      输出:

      $ make example && ./example
      cc     example.c   -o example
      Packed:     5
      Not Packed: 8
      

    【讨论】:

    • IIRC,#pragma pack 是与 MS 编译器兼容的 hack,因此仅适用于 x86 目标。如果你想移植到其他目标(但不是 VC++),你应该使用前者。如果两者都需要,则必须使用#ifdefs。
    • 我认为它也适用于其他目标,但我必须检查一下。
    • @roderigo #pragma pack 适用于 gcc 中的所有架构。在某些架构上有一个#pragma ms_struct 是为了与微软兼容
    • 但是见this question;如果你不小心,#pragma pack 可能会导致代码不安全。
    • @Edwin:不一定。例如,如果-O3 导致不安全的代码,这是一个错误(在编译器中或在它正在编译的代码中)。
    猜你喜欢
    • 2011-02-02
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 2015-05-19
    • 2015-03-22
    • 1970-01-01
    相关资源
    最近更新 更多