在 C 中将结构复制到数组时出现 PC-LINT 警告

问题描述 投票:0回答:1

这是我在 Stack Exchange 上的第一个问题,请跟随我。 在我的一个嵌入式 C 项目中,我尝试将结构数据的一部分复制到数组中。 例如:

typedef struct
{
  uint16_t Length_ui16;
  uint8_t  Message_Id_ui8;
  uint8_t  SensorPosition_ui8;
  uint8_t  SenType_ui8a[9];
  uint8_t  SenArticleNo_ui8a[9];
  uint8_t  SenSerialNo_ui8a[9];
  uint8_t  SenSoftVer_ui8a[6];
}data;

memcpy(destArr_ui8, &data.SensorPosition_ui8, 34);      

说明:我正在尝试从 SensorPosition 开始复制数据(34 字节)。 注意:结构填充和 destArr 大小已考虑在内 代码正在按照我的预期工作。但我的 PC-LINT 在这方面支持了我。

PC-LINT 警告 662:操作符“[”可能创建越界指针(超出数据末尾 33)

我的分析是,PC_LINT认为源只是一个单字节变量(SensorPosition),因此给出33字节的出站警告。

所以,真正的问题是,

  1. 是否有任何其他优雅或常用的方法也可以满足 PC_LINT 来实现相同的目标。
  2. 如果,不,我该如何更改我的代码以满足 PC_LINT 的要求。
c embedded structure
1个回答
0
投票

我很确定这是未定义的行为;是的,您知道

SensorPosition_ui8
之后会发生什么,但是当您调用
memcpy
时,您专门向该单个成员传递了一个指针,并且您超出了该成员的范围。

即使您认为 UB 在这里并不重要,仍然存在一个问题,即参与

memcpy
的成员之间可能存在填充。这不仅意味着
SensorPosition_ui8
SenSoftVer_ui8
占用超过 34 个字节,而且
destArr_ui8
很可能在
memcpy
之后有随机填充字节,而您不知道其位置或值。

我建议在这里使用

union
。除了解决您的问题之外,它还可以使源代码更干净一些。

typedef struct
{
  uint16_t Length_ui16;
  uint8_t  Message_Id_ui8;

  union
  {
    uint8_t Sensor_ui8a[34];
    struct
    {
      uint8_t  SensorPosition_ui8;
      uint8_t  SenType_ui8a[9];
      uint8_t  SenArticleNo_ui8a[9];
      uint8_t  SenSerialNo_ui8a[9];
      uint8_t  SenSoftVer_ui8a[6];
    };
  };
} data;
// ...
memcpy(destArr_ui8, data.Sensor_ui8a, sizeof data.Sensor_ui8a);
© www.soinside.com 2019 - 2024. All rights reserved.