如何解决MISRA代码中的“控制表达式不是'本质上的布尔'表达式”?

How to solve " Controlling expression is not an 'essentially Boolean' expression " in MISRA code?

提问人:user2986042 提问时间:8/3/2023 更新时间:8/7/2023 访问量:105

问:

我有一个简单的宏函数,它将检查条件并返回一个布尔值。下面是代码片段

假设:#define boolean bool

Test.h 文件

#define CHECK_STATE(X)            (boolean)(STATE_VALUE == (uint8)(X) )

Test.c 文件

enum MY_STATE{

    STATE_0,  
    STATE_1,     
    STATE_2    
};

static uint8 STATE_VALUE  = (uint8)STATE_0; //This value update in the code dynamically from state 0 to 2

if(CHECK_STATE(STATE_1))  /*MISRA warning: Controlling expression is not an 'essentially Boolean' expression. */
{
  /*If condition pass*/
}
else
{
  /*If condition failes*/
}

在上面的代码中,函数将返回一个布尔值。因此,if 循环可以检查 true 或 false。那么,为什么MISRA会发出警告“不是'本质上的布尔'表达式”呢?有什么建议可以修复此类警告吗?CHECK_STATE

C 枚举 静态分析 布尔表达式 misra

评论

1赞 0___________ 8/3/2023
(STATE_VALUE == (uint8)(X))给出布尔值
0赞 David Ranieri 8/3/2023
能解决问题吗?检查 stackoverflow.com/q/52780276/1606345if(CHECK_STATE(STATE_1) == true)
1赞 Jim Rogers 8/3/2023
如果使用 switch 语句来处理枚举MY_STATE的三个可能值中的每一个,MISRA 检查器可能会更清楚。
3赞 Eugene Sh. 8/3/2023
从宏中删除强制转换,这可能会混淆检查器(boolean)
3赞 John Bollinger 8/3/2023
"假设:#define 布尔布尔值“——我想我们也应该假设它也是 d?这似乎是不必要的间接。如果你觉得你必须有一个类型名称,那么为什么不把它定义为 内置类型 ,它不依赖于任何标头。然而,话虽如此,宏中的外部投射有点荒谬。我会放弃它。stdbool.h#includeboolean_BoolCHECK_STATE()

答:

0赞 Eva4684 8/5/2023 #1

在分析器中,您应该能够指定自定义布尔类型,例如在 PClint 中:

-strong(B,boolean) /* custom bool */

并将其定义为:

typedef uint8_t boolean;

我也更喜欢自定义布尔值,因为在许多嵌入式库/HAL 中定义了自己的布尔值,这可能会导致冲突。

0赞 Andrew 8/7/2023 #2

当然,MISRA 更希望您使用内联函数来使用类似函数的宏,以便更好地进行类型匹配......因此,您的工具缺少 D.4.9 违规!但对于手头的事情......

您的工具未正确配置为将自定义视为布尔类型;由于您的代码不必要地冗长,这更加复杂。boolean

有两种方法可以解决这个问题:

1. 简化 使用 MISRA 基本类型,并使用枚举类型

Test.h 文件

#define CHECK_STATE(X) ( STATE_VALUE == (X) )  // No casts needed!

Test.c 文件

enum MY_STATE {
    STATE_0,  
    STATE_1,     
    STATE_2    
};

static enum MY_STATE STATE_VALUE  = STATE_0; // No cast needed

if ( CHECK_STATE( STATE_1 ) ) 
{
  /*If condition pass*/
}
else
{
  /*If condition fail*/
}

2. 配置工具 请参阅@Eva4684的回答以获取提示

恕我直言,KISS 原则应该适用于这里

顺便说一句,当两个变量都是枚举都是模块范围时,为什么要在头文件中定义宏?