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

时间:2016-02-17 19:19:08

标签: c misra

我目前正在开展一个项目,该项目要求代码符合Misra 2012标准。在整个项目中,我们有许多必需的misra警告告诉我们,我们无法将指针转换为指向另一种类型的指针。像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并填充结构结构的所有元素也会引发大量警告?

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

3 个答案:

答案 0 :(得分:8)

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

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

  Rule 11.5
  A conversion should not be performed from pointer to void into
  pointer to object

  Category Advisory
  Analysis Decidable, Single Translation Unit
  Applies to C90, C99

  Rationale
  Conversion of a pointer to void into a pointer to object may result
  in a pointer that is not correctly aligned, resulting in undefined
  behaviour. It should be avoided where possible but may be necessary,
  for example when dealing with memory allocation functions. If
  conversion from a pointer to object into a pointer to void is used,
  care should be taken to ensure that any pointers produced do not
  give rise to the undefined behaviour discussed under Rule 11.3.

观察:

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

答案 1 :(得分:3)

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

在您最喜爱的搜索引擎中输入“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更好的工作,其中“更好”我的意思是“符合你的要求”。

答案 2 :(得分:1)

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

唯一有争议的规则是11.5:

  

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

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

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

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

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

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

  

Misra如何期待malloc

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