主要内容

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

MISRA C:2012 Rule 10.1

Operands shall not be of an inappropriate essential type

描述

规则定义

Operands shall not be of an inappropriate essential type 1 .

理由

什么是基本类型?

基本类型分类定义了对象或表达式的基本类型。

基本类型分类标准类型

本质上为布尔类型

bool_Bool(在 stdbool.h 中定义)

您还可以使用有效布尔类型 (-boolean-types) 选项定义本质上为布尔的类型。

本质上为字符类型

char

本质上为枚举类型

named enum

本质上为有符号类型

signed char, signed short, signed int, signed long, signed long long

本质上为无符号类型

unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long

本质上为浮点类型

实数浮点:float, double, long double

复数浮点:float _Complex, doble _Complex, long double _Complex

补充说明及理由

对于某些运算符的操作数,您无法使用特定的基本类型。在下表中,每一行代表一个运算符/操作数的组合。如果该行中的“基本类型”列不为空,则表示在将该类型用作操作数时将受 MISRA 规则的限制。表中的数字对应表后面的理由列表。

操作算术操作数的基本类型分类
运算符操作数布尔字符枚举signed无符号浮点
实数复数
[ ]整数34   19
+(一元) 345    
-(一元) 345 8  
+ -任一3 5    
++ -- 3 5   9
* /任一345    
%任一345  19
< > <= >=任一3     9
== !=任一     1010
! && ||任意 222222
<< >>345、66 19
<< >>3477 19
~ & | ^任意345、66 19
?:第一个 222222
?:第二个和第三个       

  1. 这些操作数的表达式本质上为浮点类型,这违反了约束。

  2. 当一个操作数被解释为布尔值时,请使用本质上为布尔类型的表达式。

  3. 当一个操作数被解释为数字值时,不要使用本质上为布尔类型的操作数。

  4. 当一个操作数被解释为数字值时,不要使用本质上为字符类型的操作数。字符数据的数值由实现定义。

  5. 在算术运算中,不要使用本质上为枚举类型的操作数。枚举对象使用实现定义的整数类型。因此,涉及枚举对象的运算可能会产生类型出乎意料的结果。

  6. 仅对本质上为无符号类型的操作数执行移位和位运算。当对本质上为有符号的类型使用移位和位运算时,结果的数值是未定义的或由实现定义的。

  7. 为了避免负位移操作导致的未定义行为,请使用本质上为无符号的右操作数。

  8. 对于一元减运算符,不要使用本质上为无符号类型的操作数。int 类型的实际实现大小决定了结果的符号性。

  9. 这些操作数的本质上为复数浮点类型的表达式违反了约束。

  10. 比较浮点类型可能会导致意外且与实现相关的结果。比较浮点类型时,请考虑浮点精度 (FLT_EPSILON) 和数字的大小。

请注意,对于位字段类型,如果位字段实现为:

  • 布尔值,位字段基本上为布尔值。

  • 有符号或无符号类型,位字段本质上分别为有符号或无符号的。

    位字段的类型是能够表示位字段的最小类型。例如,这里的类型 stmp 本质上是一个 8 位整数:

    typedef signed int mybitfield;
    typedef struct { mybitfield f1 : 1; } stmp;

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

Polyspace 实现

当运算的操作数为不适当的基本类型时,Polyspace® 会报告违反此规则。作为例外,Polyspace 不会报告以下使用情况下的违规行为:

  • 使用一个本质上为有符号类型的非负整数常量表达式作为移位运算符的右操作数。

  • 将本质上为实数的浮点或基本为复数浮点的对象与常量零或宏 INFINITY-INFINITY 进行比较。

故障排除

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

示例

全部展开

#include<stdbool.h>
extern float f32a;
extern char cha; 
extern signed char s8a;
extern unsigned char u8a,u8b,ru8a;
enum enuma { a1, a2, a3 } ena, enb; 	
extern bool bla, blb, rbla; 
void foo(void) {

	rbla = cha && bla;        /* Non-compliant: cha is essentially char  */
	enb = ena ? a1 : a2;      /* Non-compliant: ena is essentially enum  */
	rbla = s8a && bla;        /* Non-compliant: s8a is essentially signed char  */
	ena = u8a ? a1 : a2;      /* Non-compliant: u8a is essentially unsigned char  */
	rbla = f32a && bla;       /* Non-compliant: f32a is essentially float */
	rbla = bla && blb;        /* Compliant */
	ru8a = bla ? u8a : u8b;   /* Compliant */
}

在不合规的示例中,规则 10.1 被违反,原因如下:

  • 操作符 && 仅接受本质上为布尔型的操作数。然而,至少有一个操作数使用的类型不同。

  • ?: 的第一个操作数期望本质上为布尔类型的值。然而,这里使用了不同的操作数类型。

注意

要使 Polyspace 检测到规则违规,您必须将类型名称 boolean 定义为有效的布尔类型。有关详细信息,请参阅Effective boolean types (-boolean-types)

#include<stdbool.h>
enum enuma { a1, a2, a3 } ena; 
enum { K1 = 1, K2 = 2 };    /* Essentially signed */
extern char cha, chb; 
extern bool bla, blb, rbla; 
extern signed char rs8a, s8a;
extern unsigned char u8a;

void foo(void) {

  rbla = bla * blb;      /* Non-compliant - Boolean used as a numeric value */
  rbla = bla > blb;      /* Non-compliant - Boolean used as a numeric value */

  rbla = bla && blb;     /* Compliant */
  rbla = cha > chb;      /* Compliant */
  rbla = ena > a1;       /* Compliant */ 
  rbla = u8a > 0U;       /* Compliant */
  rs8a = K1 * s8a;       /* Compliant - K1 obtained from anonymous enum */

}

在不合规的示例中,违反了规则 10.1,因为运算符 *> 不期望本质上为布尔类型的操作数。然而,这里使用的操作数本质上为布尔值。

注意

要使 Polyspace 检测到规则违规,您必须将类型名称 boolean 定义为有效的布尔类型。有关详细信息,请参阅Effective boolean types (-boolean-types)

extern char rcha, cha, chb; 
extern unsigned char ru8a, u8a;

void foo(void) {

  rcha = cha & chb;      /* Non-compliant - char type used as a numeric value */
  rcha = cha << 1;       /* Non-compliant - char type used as a numeric value */

  ru8a = u8a & 2U;       /* Compliant */	
  ru8a = u8a << 2U;      /* Compliant */
 
}

在不合规的示例中,违反了规则 10.1,因为运算符 &<< 不期望本质上为字符类型的操作数。但是,这里使用的至少一个操作数本质上为字符类型。

typedef unsigned char boolean;

enum enuma { a1, a2, a3 } rena, ena, enb; 

void foo(void) {

  ena--;             /* Non-Compliant - arithmetic operation with enum type*/
  rena = ena * a1;   /* Non-Compliant - arithmetic operation with enum type*/
  ena += a1;         /* Non-Compliant - arithmetic operation with enum type*/

}

在不合规的示例中,规则 10.1 被违反,因为算术运算符 --*+= 不期望本质上为枚举类型的操作数。然而,这里使用的至少一个操作数本质上为枚举类型。

extern signed char s8a;
extern unsigned char ru8a, u8a;

void foo(void) {

  ru8a = s8a & 2;       /* Non-compliant - bitwise operation on signed type */
  ru8a = 2 << 3U;       /* Non-compliant - shift operation on signed type */
	
  ru8a = u8a << 2U;     /* Compliant */	

}

在不合规的示例中,违反了规则 10.1,因为不能对本质上为有符号的操作数执行 &<< 运算。然而,这里使用的操作数是有符号的。

extern signed char s8a;
extern unsigned char ru8a, u8a;

void foo(void) {

  ru8a = u8a << s8a;    /* Non-compliant - shift magnitude uses signed type */	
  ru8a = u8a << -1;     /* Non-compliant - shift magnitude uses signed type */	

  ru8a = u8a << 2U;     /* Compliant */	
  ru8a = u8a << 1;      /* Compliant - exception */	

}

在不合规的示例中,违反了规则 10.1,因为运算 << 不期望一个本质上为有符号类型的右操作数。然而,这里使用的正确操作数是有符号的。

#include <complex.h>
#include <stdbool.h>
#include <math.h>
_Complex float cnx, cny;
float fx;
void amd3() {

      cnx ? 1 : 0;                    // Noncompliant
      cny = !cnx;                     // Noncompliant
      cny = cnx && cny;               // Noncompliant
      cny = cnx || cny;               // Noncompliant
      if(fx != 0.0f) // Compliant
      {}
      if(cnx != INFINITY) // Compliant
      {}
}

在示例中,Polyspace 报告了违反规则 10.1 的情况,因为本质上为浮点类型的操作数与运算符 ==!= 一起使用。作为例外情况,使用这些运算符将本质上为浮点类型的操作数与 0.0fINFINITY 进行比较并不违反规则。

检查信息

组:基本类型模型
类别:必需
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.