简体   繁体   English

指针 alignment 与 MISRA-C 2012 不兼容

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

I'm trying to convert a certain pointer as follows:我正在尝试按如下方式转换某个指针:

I have this struct:我有这个结构:

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;

and trying to perform this conversion:并尝试执行此转换:

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

This conversion is not MISRA compliant (according to rule 11.3) since the data is not aligned properly.此转换不符合 MISRA(根据规则 11.3),因为数据未正确对齐。 I tried to align the address according to this following solution but it compile (Error: "expression must have integral typeC/C++(31)"):我尝试根据以下解决方案对齐地址,但它编译(错误:“表达式必须具有整数类型 C/C++(31)”):

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

Could use some help if anyone has any better ideas here:)如果有人在这里有更好的想法,可以使用一些帮助:)

You simply cannot do wild pointer conversions like this in C.您根本无法在 C 中进行像这样的野指针转换。 Alignment isn't the only issue, but also strict pointer aliasing and portability. Alignment 不是唯一的问题,还有严格的指针别名和可移植性。

Regarding alignment/padding, adding uint8_t padding[3];关于对齐/填充,添加uint8_t padding[3]; at the end achieves nothing - if there was need for padding there, the compiler would have added it automatically.最后什么也没做——如果那里需要填充,编译器会自动添加它。

You need to rewrite the code.你需要重写代码。 This is one option:这是一种选择:

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;

Unfortunately union is problematic with other MISRA-C rules but in this case you are using it for type punning rather than for storing unrelated data in the same memory location, which is what MISRA-C forbids with the union rule, so deviations are possible and sensible.不幸的是, union在其他 MISRA-C 规则中存在问题,但在这种情况下,您将其用于类型双关语,而不是将不相关的数据存储在同一 memory 位置,这是 MISRA-C 禁止union规则的内容,因此可能存在偏差并且明智的。

Using C11 anonymous union should be fine too far as I can tell from MISRA-C:2012 amendment 2. It might confuse your static analyser though, in case it doesn't support C11.从 MISRA-C:2012 修正案 2 中可以看出,使用 C11 匿名联合应该很好。不过,如果它不支持 C11,它可能会使您的 static 分析器感到困惑。 Example:例子:

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;

Another option is memcpy .另一种选择是memcpy

As noted before, alignment is just a part of Rule 11. 3 rationale.如前所述,alignment 只是规则 11. 3基本原理的一部分。 Indeed, it's about (prohibiting of) type punning.实际上,它是关于(禁止)类型双关语的。

As far as I understand, there is no way to do what you need if all MISRA rules are enabled.据我了解,如果启用了所有MISRA 规则,则无法执行您需要的操作。 But if the code in question is for communication tasks where there are many different packet formats, flexible header etc., it is very likely that Rule 11. 5 ( "A conversion should not be performed from pointer to void into pointer to object" ) is already disabled.但是如果有问题的代码用于有许多不同数据包格式的通信任务,灵活的 header 等,则很可能规则 11. 5“不应执行从指针到 void 到指针到对象的转换” )已经被禁用。

If so, one can use:如果是这样,可以使用:

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;

(Note that rules 11.3 and 11.4 uses "between... and...", and rule 11.5 uses "from... to...") (注意规则 11.3 和 11.4 使用“介于...和...”,规则 11.5 使用“从...到...”)

If it is possible, I prefer to use transitional void * pointers (as function parameters or local variables) to avoid cascaded casts and make code more readable.如果可能的话,我更喜欢使用过渡 void * 指针(如 function 参数或局部变量)来避免级联转换并使代码更具可读性。

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

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