是否有必要使用数据结构对齐

时间:2017-02-05 15:30:00

标签: c structure memory-alignment

我正在为32位MCU读取此代码。

我的问题是 - 是否有必要使用__attribute__((packed, aligned(1)))?这只是一种很好的做法,或者如果没有它会导致不可预测的行为。

typedef struct  __attribute__((packed, aligned(1))) radio_packet {
  uint8_t tag;               /* 1 byte  */
  uint32_t id;               /* 4 bytes */
  uint16_t size;             /* 2 bytes */
  uint16_t element;          /* 2 bytes */
  uint8_t  length;          /* 1 byte  */ 
  // The items above comprise HDR_SIZ
  uint8_t data[PKT_SIZ]; 

} radio_packet_t;

2 个答案:

答案 0 :(得分:3)

  

这是不错的做法还是会导致不可预测的行为呢?

两者都不是。如果打包与否的数据只在程序中使用,那么最好让编译器选择如何排序这些数据以及如何对齐它们 - 除非你真的想保存ram。

如果数据必须具有特定格式 - 我认为是,因为您的结构名为“radio_packet”,那么您需要确保您所编写的格式受到尊重。在这种情况下,您希望打包数据,并在格式请求时手动插入填充。

在这种特殊情况下,结构的名称让我认为数据包将被传输到其他设备,这些设备将运行可能使用不同编译器编写的软件。因此,您不希望编译器干扰字段的顺序和位置。换句话说,该结构仅在程序中使用

进一步扩展。在正常情况下,不使用 打包和/或对齐是一种很好的做法,因为编译器比人类更了解什么是最好的。当您知道比编译器做得更好时,可以使用打包/对齐,例如,因为您必须遵守编译器不知道的某种格式。通常(但取决于编译器),它可以选择优化性能,也许会浪费一些内存。为了获得最大性能,它可以将字段与CPU的首选对齐方式对齐,插入未使用/隐藏的字段,甚至重新排序。如果您随后将该数据包发送到某些不使用相同填充/对齐的硬件或软件,这是不好的:32位CPU更喜欢32位对齐数据,但8位CPU无关紧要。 / p>

从程序/ CPU的角度来看,在任何一种情况下都不会出现不可预测的行为。编译器非常清楚它正在做什么,即使你强加了一些限制。当数据格式错误,进入/退出程序时,会发生错误或[可能不那么]不可预测的行为。

答案 1 :(得分:0)

没有必要,但您可以稍后在代码中进行假设。例如,您可以从char数组到radio_packet_t执行安全memcpy,并且程序中的所有组件都不需要知道类型radio_packet_t,并且可以使用字节缓冲区通过networkd或文件或其他任何方式发送radio_packet_t。