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

Is it necessary to use Data structure 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;

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

Is this just good practice or does it cause unpredictable behavior without it?

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

如果数据 必须 具有特定格式 - 我认为是的,因为您的结构被命名为 "radio_packet",那么您要确保您的格式写被尊重。在这种情况下,您想要打包数据,并在格式要求时手动插入填充。

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

进一步扩展。在正常情况下,最好 不要使用 packing and/or aligning,因为编译器比人类更清楚什么是最好的。当您比编译器知道该怎么做时,您可以使用 packing/aligning,例如,因为您必须遵守编译器不知道的某些格式。通常(但取决于编译器),它会做出优化性能的选择,也许会浪费一些内存。为了实现最佳性能,它可以将字段对齐到 CPU 的首选对齐方式,插入 unused/hidden 字段甚至重新排序它们。如果您随后将该数据包发送到某些不使用相同 padding/alignment 的硬件或软件,这就不好了:32 位 CPU 更喜欢 32 位对齐数据,但 8 位CPU无所谓。

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