主要内容

MISRA C:2012 Rule 10.1

R2026b

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 规则的限制。表中的数字对应表后面的理由列表。

运算算术操作数的本质类型分类
运算符操作数布尔字符枚举有符号无符号浮点
实数复数
[ ]整数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 Type Model Used in MISRA C Rule Checking。

Polyspace 实现

当某个运算的操作数具有不适当的本质类型时,Polyspace® 会报告违反了此规则。作为例外,Polyspace 不会对以下用例报告违规:

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

  • 将本质实数浮点对象或本质复数浮点对象与常量字面值 0 或宏 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.0f 和 INFINITY 进行比较时,不算违规。

检查信息

组:基本类型模型
类别:必需
AGC 类别:建议
PQL 名称:std.misra_c_2012.R10_1

版本历史记录

全部展开


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:2025

  • MISRA C++:2008

  • MISRA C++:2023

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