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

thu*_*ird 4 c misra

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

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

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

小智 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. 理提供了指针转换时对象的指针作废做什么,完全符合了OP想有行指导("信息,要求我们要仔细检查包装,定位和其他任何可能出错").


Eri*_*ert 5

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

在您最喜欢的搜索引擎中输入“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 做得更好,其中“更好”是指“符合您的要求”。

  • @SergeyA:这是您的选择:(1) 使用具有适当类型系统和运行时的语言来确保内存安全,并支付与之相关的性能成本。(2) 使用一种带有垃圾类型系统的语言,让您可以将任何引用转换为任何其他引用,编写使用 void* 作为任何类型代理的代码,支付严重到让您掉头发的错误的成本,或者(3) 使用带有垃圾类型系统的语言,避免使用 void*,编写大量无聊的代码。我选择 (1),但那是因为这些语言不仅能满足我的需求。 (4认同)
  • @SergeyA:我坦率地承认我不是 C++ 专家,甚至从未编写过一个 C++ 编译器;我只用 C++ 为*其他*语言编写过编译器。直到你为它编写了几个编译器之后,你才真正了解一种语言。也就是说,我想我可能偶尔会在这个主题上增加一些价值。 (4认同)
  • @thunderbird:* 经常* 的情况是,遵守并非针对您的特定应用严格定制的标准会增加工作和效率方面的成本。成本是否值得收益的问题由您和项目利益相关者共同决定,基于对成本和收益的知情评估。合规本身并不好;这是因为有好的结果。如果你没有以合理的成本获得那些好的结果,那就推迟吧。 (3认同)
  • @SergeyA:谁说过要编写通用内存管理器?你需要一个整数块,**写一个内存管理器专门让你成为一个整数块**。广义的内存管理器是一堆危险;该标准的全部意义在于摆脱这种危险,而不是重新实施它。 (3认同)
  • @SergeyA:是的,所以有一个很好的例子。如果性能成本超过安全收益,那么您可以提出一个有原则的、数据驱动的论点,即序列化代码应该被*隔离*到它自己的隔离子系统中,该子系统经过仔细审查,并且不受您的需求策略的约束。政策是我们的仆人;让你的工作来实现你的目标。 (2认同)