主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

MISRA C:2012 Rule 10.8

The value of a composite expression shall not be cast to a different essential type category or a wider essential type

描述

规则定义

The value of a composite expression shall not be cast to a different essential type category or a wider essential type 1 .

理由

一个复合表达式 是使用复合运算符的非常量表达式。在基本类型模型中,复合运算符包括:

  • 乘法运算符(*/%

  • 加法运算符(二进制 +、二进制 -

  • 位运算符(&|^

  • 移位运算符(<<>>

  • 条件运算符(?:

一元运算符如 ~ 以及一元运算符 +- 也被视为复合运算符。

不允许将类型转换为更广泛的类型,因为不同实现中的结果可能不一致。请考虑以下表达式:

(uint32_t) (u16a +u16b);
在 16 位机器上,加法运算以 16 位形式进行。结果在转换为 32 位之前已发生溢出(截断)。在 32 位机器上,加法运算在 32 位范围内进行,并保留在 16 位机器上会丢失的高位。将类型转换为具有相同基本类型类别的更窄类型是可以接受的,因为显式截断结果总是会导致相同的信息丢失。

有关基本类型的详细信息,请参阅Essential Types in MISRA C Rules 10.x

Polyspace 实现

规则检查器严格遵循该规则的 MISRA C™:2012 规范,只有当复合表达式的结果被直接转换为不同的或更宽的基本类型时,才会报告缺陷。一元运算符不被视为复合运算符。

例如,在此示例中,第一个赋值给 i 时出现违规,但第二个赋值时未出现违规。在第一个作业中,复合表达式 i+1 从有符号类型直接转换为无符号类型。在第二个作业中,复合表达式首先被转换为同一类型,然后将结果转换为另一种类型。由于复合表达式未直接转换为不同的类型,因此检查项不会报告违规。

typedef int int32_T;
typedef unsigned char uint8_T; 
...
...
int32_T i;
i = (uint8_T)(i+1); /* Noncompliant */
i = (uint8_T)((int32_T)(i+1)); /* Compliant */

Polyspace® 在以下情况下不会报告违反此规则的情况:

  • 一个本质上为实数的浮点表达式被转换为一个本质上为复数的浮点类型,但该复数类型的对应实数类型不宽于实数表达式的类型。

  • 一个本质上为实数的复数表达式被转换为一个本质上为实数的浮点类型,但该浮点类型不比复数表达式的对应实数类型更宽。

故障排除

如果您预期会出现违规,但未看到该违规,请参阅诊断为何编码规范违规未按预期显示

示例

全部展开

在此示例中,以下情况违反了规则 10.8:

#include <stdint.h>
#include <complex.h>
extern unsigned short ru16a, u16a, u16b;
extern unsigned int   u32a, ru32a;
extern signed int     s32a, s32b;

void foo(void)
{
  ru16a  = (unsigned short) (u32a + u32a);/* Compliant                           */
  ru16a += (unsigned short) s32a;    /* Compliant - s32a is not composite        */
  ru32a  = (unsigned int) (u16a + u16b);  /* Noncompliant - wider essential type */
}

void bar(int8_t i8x, int8_t i8y, float fx, float fy){
	
	(_Complex float) (i8x + i8y);      /* Noncompliant - wider essential type */ 
	 (_Complex float) (fx + fy);       /* Compliant                           */    
}

  • s32as32b 本质上为 signed 变量。然而,结果 ( s32a + s32b ) 被转换为本质上为 unsigned 类型的值。

  • u16au16b 本质上为 unsigned short 变量。然而,结果 ( s32a + s32b ) 被转换为更宽的基本类型 unsigned int

  • i8xi8y 本质上为 8 位有符号整数,但会被转换为更宽的基本类型 _complex float

检查信息

组:基本类型模型
类别:必需
AGC 类别:建议

版本历史记录

全部展开


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.