米斯拉2012背后的理由不允许在不同的指针之间施放

我目前正在开展一个项目,要求代码符合Misra 2012标准。 在整个项目中,我们有许多必需的misra警告告诉我们,我们无法将指针转换为指向另一种类型的指针。 像void *memcpy(void *to, const void *from, size_t n)这样简单的事情void *memcpy(void *to, const void *from, size_t n)产生两个Misra Required警告,因为需要分别将类型转换为void *和const void *。 从void *转换为指向任何其他类型的指针也会产生Misra警告。

我的问题是Misra如何在不抛出任何警告的情况下期望malloc和其他所有工作? 即使将void * buffer转换为uint8_t * buffer来逐字节解析abuffer并填充结构结构的所有元素也会引发大量警告?

而不是这些警告,它不仅可以显示使用注释或信息要求我们仔细检查包装,对齐和其他可能出错的地方吗?

我想回到OP所要求的内容并直接得到一些东西。 首先,调用void * memcpy(void * to,const void * from,size_t n)没有问题,因为指向对象的指针到void指针的转换不违反任何MISRA-C:2012准则。 换句话说,任何产生违规行为的工具都是错误的。

其次,在得出任何结论之前,重要的是要阅读规则11.5,即相关的MISRA-C:2012指南,实际上是说:

  细则11.5
  不应该从指向void的指针执行转换
  指向对象的指针

  分类咨询
  分析可判定单翻译单元
  适用于C90,C99

  合理
  可能会导致将指向void的指针转换为指向对象的指针
  在未正确对齐的指针中,导致未定义
  行为。 应尽可能避免,但可能是必要的,
  例如,在处理内存分配函数时。 如果
  使用从指针到对象的转换为指向void的指针,
  应该注意确保所产生的任何指针都没有
  引起规则11.3中讨论的未定义行为。

观察:

  1. 它是一个咨询规则(即既不要求也不强制),因此可以偏离,MISRA定义了正确的偏差过程;
  2. 将指向对象的指针转换为指向void的指针很好:这是相反的问题;
  3. 该基本原理明确提到了内存分配函数(是的,使用动态内存分配的程序可以符合MISRA-C:2012);
  4. 基本原理提供了在将指针转换为指针到指向void时要做什么的指导,完全符合OP想要的(“信息要求我们仔细检查打包,对齐以及可能出错的任何其他内容”)。

这不能回答你的问题,这是关于理由的。 相反,它指出你不应该首先处于这种情况。

在您最喜爱的搜索引擎中输入“misra malloc”会引导我们:

http://www.misra.org.uk/forum/viewtopic.php?t=260

哪问:

根据规则,我们不应该使用malloc(),free(),calloc()等函数。但malloc()是一个非常常见的要求。 大多数嵌入式系统应用程序使用自己的应用程序级别的内存管理器,以便快速进行分配和解除分配。 你有什么建议来解决这个问题(如果我们不能使用malloc,任何其他方式)?

答案是:

我们被问及有关MISRA C1和MISRA C2中禁止的各种事项的解决方案和解决方法,例如使用malloc,calloc等进行动态内存分配。 MISRA或MISRA C工作组的任何成员都不会对任何偏差或“变通方法”给予任何指导或批准。


您要求代码符合特定标准。 您使用的机制不符合该标准。 要么找出一种原则性强有力的遵守方式,要么就如何处理故意违规提出明确的政策。

例如,你提到memcpy。 这是不合规的。 所以退后一步,问“假设我没有任何memcpy的实现。 我怎么写自己的memcpy是合规的 ?” 您正在使用memcpy来解决问题; 没有它解决问题。

现在对malloc做同样的事情。 有一天malloc不存在,有人不得不用malloc写它。 你有一个由malloc解决的问题。 如果你没有malloc,你会如何解决它? malloc中没有任何东西是神奇的; 你可以自己写一个比malloc更好的工作,其中“更好”我的意思是“符合你的要求”。

MISRA-C:2012在指针转换方面实际上有些松懈。 大多数规则是合理的,关注强迫你遵循C标准,不是调用未定义的行为,或者做一些普遍的坏事,比如从指针中抛弃const限定符。 你不应该反对任何一个。

唯一有争议的规则是11.5:

不应该从指向void的指针到指向对象的指针执行转换。

我认为这是导致你头痛的原因。 基本原理是不兼容的指针类型之间的对齐关注和转换,这将导致未定义的行为。

该规则确实间接禁止使用许多基本的库函数,如memcpy 。 我在2012年审查期间向MISRA就此规则提出的个人建议如下:

(非常不同意)“当无效指针强制转换是必要的时候,通用C编程的情况太多了。这个规则不实用,弊大于利。相反,制定规则禁止规则试图防范的特定危险,即“指向x的指针,转换为void *,转换为指向y的指针”。

但是他们没有听,而且你有它:一个无用的规则迫使每个工具都喷出大量的误报。 这意味着MISRA的每个用户都必须忽略此规则。 它是咨询性的,因此您可以忽略它而不会引发任何偏差程序。 只需在静态分析仪中阻止它并继续前进即可。

MISRA委员会尚未意识到误报本身就是一种安全隐患,因为它可能导致人们开始重写完美的代码,从而引入错误。

Misra如何期待malloc

MISRA希望你根本不使用malloc,由于非常合理的原因,它明确被指令4.12禁止。 但这是另一个话题。