【问题标题】:Copy values from one array to other array without using pointer arithmetic不使用指针算法将值从一个数组复制到另一个数组
【发布时间】:2020-03-25 15:45:48
【问题描述】:

我正在使用这个函数将一些值从一个数组复制到另一个数组:

void *copy_array(const void *src, void *dest, uint8 pos, uint8 len, uint8 elemsize)
{
   const unsigned char *csrc = src;

   memcpy(dest, csrc + (pos * elemsize), len * elemsize);
}

有没有类似的方法可以在不使用指针算法的情况下做到这一点? MISRA 建议避免使用指针算法。

【问题讨论】:

  • 如果要在生产软件中使用,没有充分的理由避免在此代码中使用指针运算。这是课堂练习吗?如果是这样,实际的问题陈述是什么?可以认为“指针运算”发生在不同的概念级别——C 源代码中的显式表达式、数组引用等隐式表达式以及机器级别。在后一层,不可能避免指针运算,因为需要内存地址来加载数据,因此必须计算。真正的问题是什么?
  • 答案取决于您需要的“相似度”级别 ;-) 如果您需要 misra 合规性,我建议尽可能避免接受或返回 void*
  • IMO 这里的主要问题是首先有空指针。
  • C 代码不能是类型安全和通用的,所以你必须选择一个 - 如果你需要 MISRA 合规性,选择不是你的 - 可悲的答案是,你不能实现这个以安全的方式辅助函数。
  • 基本上,MISRA 规则不希望你搞砸指针算术,因为你可能会把它搞砸。但是这个例程只传递地址、元素大小和元素索引。这意味着它无法在不计算地址(直接或间接)的情况下完成其工作,并且任何调用它的人都已经冒了 MISRA 想要通过分解其高级对象(例如数组)来避免的风险已知类型) 成块,例如元素大小。在这个例程中你可能做的最好的事情是const uint8 (*x)[elemsize] = src; memcpy(dest, &x[pos], len * sizeof *x);

标签: c arrays memory misra


【解决方案1】:

要符合 MISRA,只需执行memcpy(dest, &csrc[pos * elemsize], len * elemsize);

虽然我不太明白你为什么需要一个函数,而不是直接调用memcpy。正如 cmets 中所述,MISRA 不赞成通过咨询规则使用 void 指针,因为关键任务软件应该是确定性的,而不是通用的。

另外,len * elemsize 相当有问题,因为这会将函数限制为最大 255 字节的数组。

您可以通过将函数转换为类似函数的宏来潜在地避免许多 MISRA 问题。不一定是提高可读性,但据我所知,这应该符合 MISRA:

#define copy_array(src, dst, pos, len, elemsize) \
  memcpy((dst), &(src)[(pos)*(elemsize)], (len)*(elemsize))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 2021-02-07
    • 2015-10-26
    • 2018-04-16
    相关资源
    最近更新 更多