【问题标题】:MISRA C compliance for arithmetic addition算术加法的 MISRA C 合规性
【发布时间】:2015-08-05 17:11:44
【问题描述】:

给定变量abc

uint32_t a;
uint16_t b, c;

根据 MISRA-C 2012 标准,表达式 a+b+c 是合规的,而 b+c+a 是不合规的。

为什么?

【问题讨论】:

  • 老实说,这个问题太神秘了……
  • 抱歉,问题应该是 U32a+u16b+u16c 符合 MISRA-C 而 U16a+u16b+u32c 不符合。
  • @ramsurada 什么是“MISRA C”?什么是“u32a”、“u16c”、“u16c”? (我知道答案,但我敢打赌,对于这个网站的大多数成员来说,答案并不明显。)
  • @Tavian MISRA-C 是一个编码标准框架,供开发人员提供证据证明对 C 语言结构的认识和/或避免导致行为由标准(即未定义、未指定和实现特定的行为)。这也适用于定义明确的 C 语言结构(经过多年的实践),会导致(或强烈暗示)意外行为。请参阅 misra-c.com
  • 引用规则编号。

标签: c misra


【解决方案1】:

对于u16a+u16b+u32cu16a+u16bunsigned(认为是 16 位)加法,在随后加法到 u32c 之前会丢失潜在的溢出。

u32a+u16b+u16c 添加u32a+u16b,然后在添加16c 时使用此 32 位结果以防止此丢失。

例子

0x8000 + 0x8000 + 0x10000 
(0x8000 + 0x8000) + 0x10000 
0 + 0x10000 
0x10000 

对比

0x10000 + 0x8000 + 0x8000
(0x10000 + 0x8000) + 0x8000
0x18000 + 0x8000
0x20000 

【讨论】:

    【解决方案2】:

    由于 C 允许自动执行不同算术类型之间的赋值,因此使用这些隐式转换可能会导致意外结果,并可能丢失值、符号或精度。 MISRA_C:2012 通过其“基本类型”模型强制执行强类型,以帮助在可能发生这种情况时发出警告 - 称为 10.x 规则。

    在这种情况下,u16a+u16b+u32c 可能会导致溢出丢失

    具体而言,这是违反 MISRA C:2012 Rule-10.7:“如果复合表达式用作执行通常算术转换的运算符的一个操作数,则另一个操作数不应具有更广泛的基本类型”。

    假设评估受更广泛的类型影响是一个常见的错误。表达式的类型实际上是由它的操作数在任何整数提升后的类型决定的。您可以通过转换为更宽的类型来解决此问题,或者重新排列表达式开头的操作数,如您在第一个示例中所示:u32a+u16b+u16c

    注意:这并不意味着表达式中的所有操作数都具有相同的基本类型。表达式 u32a + u16b + u16c 是兼容的,因为这两个加法理论上都将在 uint32_t 类型中执行。

    【讨论】:

    • 非常感谢 Chux、rici 和 Veriloud。我现在明白了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 1970-01-01
    • 2015-12-09
    • 1970-01-01
    • 2020-12-01
    • 2018-10-04
    • 2023-01-10
    相关资源
    最近更新 更多