繁体   English   中英

指针 alignment 与 MISRA-C 2012 不兼容

[英]Pointer alignment not compatible with MISRA-C 2012

我正在尝试按如下方式转换某个指针:

我有这个结构:

typedef struct {
  /** Interface index */
  uint8_t if_index;

  /** flags */
  uint32_t flags; /* error */

  /** packet id */
  uint32_t packet_id;

  /** structure must be aligned to 32 bit */
  uint8_t padding[3];

} v2x_tx_indication_value_t;

并尝试执行此转换:

lmac_cv2x_tx_packet_id_t *packet_id_ptr = NULL;
packet_id_ptr = (lmac_cv2x_tx_packet_id_t *)&tx_ind_ptr->packet_id;

此转换不符合 MISRA(根据规则 11.3),因为数据未正确对齐。 我尝试根据以下解决方案对齐地址,但它编译(错误:“表达式必须具有整数类型 C/C++(31)”):

if ((address & 0x3) == 0) {
    packet_id_ptr = (lmac_cv2x_tx_packet_id_t *)&tx_ind_ptr->packet_id;
}

如果有人在这里有更好的想法,可以使用一些帮助:)

您根本无法在 C 中进行像这样的野指针转换。 Alignment 不是唯一的问题,还有严格的指针别名和可移植性。

关于对齐/填充,添加uint8_t padding[3]; 最后什么也没做——如果那里需要填充,编译器会自动添加它。

你需要重写代码。 这是一种选择:

typedef union
{
  lmac_cv2x_tx_packet_id_t stuff;
  uint32_t packet_id;
} packet_id_t;

typedef struct {
  /** Interface index */
  uint8_t if_index;

  /** flags */
  uint32_t flags; /* error */

  /** packet id */
  packet_id_t packet;
 
} v2x_tx_indication_value_t;

不幸的是, union在其他 MISRA-C 规则中存在问题,但在这种情况下,您将其用于类型双关语,而不是将不相关的数据存储在同一 memory 位置,这是 MISRA-C 禁止union规则的内容,因此可能存在偏差并且明智的。

从 MISRA-C:2012 修正案 2 中可以看出,使用 C11 匿名联合应该很好。不过,如果它不支持 C11,它可能会使您的 static 分析器感到困惑。 例子:

typedef struct {
  /** Interface index */
  uint8_t if_index;

  /** flags */
  uint32_t flags; /* error */

  /** packet id */
  union // C11 anonymous union
  {
    lmac_cv2x_tx_packet_id_t stuff;
    uint32_t packet_id;
  };

} v2x_tx_indication_value_t;

另一种选择是memcpy

如前所述,alignment 只是规则 11. 3基本原理的一部分。 实际上,它是关于(禁止)类型双关语的。

据我了解,如果启用了所有MISRA 规则,则无法执行您需要的操作。 但是如果有问题的代码用于有许多不同数据包格式的通信任务,灵活的 header 等,则很可能规则 11. 5“不应执行从指针到 void 到指针到对象的转换” )已经被禁用。

如果是这样,可以使用:

lmac_cv2x_tx_packet_id_t *packet_id_ptr = NULL;
packet_id_ptr = (lmac_cv2x_tx_packet_id_t *)(void*)&tx_ind_ptr->packet_id;

(注意规则 11.3 和 11.4 使用“介于...和...”,规则 11.5 使用“从...到...”)

如果可能的话,我更喜欢使用过渡 void * 指针(如 function 参数或局部变量)来避免级联转换并使代码更具可读性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM