问题描述
我已经为以下用 C 编写的代码运行了 MISRA。我有一个三元运算符来查找输入类型。这是我写的一段代码。
typedef enum{
type0 = 0,type1,type2
}my_values;
#define get_type() (uint8)((bool_type0()) ? (type0) : ( (bool_type1()) ? type1 : type2 ))
/* Here bool_type0() and bool_type1() are outside functions which return bool values */
function1 ()
{
uint8 type_value = 0U;
type_value = get_type();
if((type_value == type0) || (type_value == type1 ))
{
//update the logic
}
else
{
//update the logic
}
}
运行 MISRA 后,我收到以下警告:
我不明白第一个警告有什么问题。在第二个警告中,如何将枚举更改为无符号值?我想我必须将两个操作数都更改为无符号值。在不更改枚举类型的情况下,如何修复这些错误?有什么建议吗?
解决方法
三元运算符的第一个操作数具有不适当的基本类型“无符号字符”
第一个操作数需要是布尔值。您的工具没有意识到代码中对应于 boolean in 的类型。
需要配置 MISRA-C 的每个静态分析器,以便它知道哪种类型是布尔类型,因为它向后兼容没有布尔类型的 C90。如果您使用的是 bool
或 _Bool
,那么您必须这样做是非常糟糕的,但这显然是您选择的工具的工作方式。
运算符“==”的操作数没有相同的基本类型类别:一个是“无符号”,另一个是“枚举”
这是一个正确的诊断,您不应该将枚举(枚举变量或枚举常量)与 MISRA-C 合规性的整数值进行比较,而只能与它们自己的枚举类型进行比较。您需要研究 MISRA-C:2012 中的基本类型规则才能理解这一点,有一个方便的表格,您可以在其中查看某个运算符的哪些类型可以/不能与哪些其他类型一起使用。
很容易修复:(my_values)type_value == type0
。
让我们分解一下...
- 您将
type_value
声明/定义为uint8
uint8 type_value = 0U;
-
那么你正在使用那个凌乱的宏...
#define get_type() (uint8)((bool_type0()) ? (type0) : ( (bool_type1()) ? type1 : type2 ))
/* 这里 bool_type0() 和 bool_type1() 是返回 bool 值的外部函数 */
type_value = get_type();
所以让我们扩展宏...
type_value = (uint8)( ( bool_type0() )
? ( type0 )
: ( ( bool_type1() ) ? type1 : type2 ) )
首先,当 type_value
包含枚举值时,为什么它是 uint8
...将其声明为 enum my_values
除此之外,我看不出任何明显错误,部分是由于不必要且令人困惑的宏。
enum my_values type_value = bool_type0() ? type0 : ( bool_type1() ? type1 : type2 );
这表明您的工具没有正确配置用于检测布尔值...并且将 bool
(实际上是 uint8_t
,它是一个 unsigned char
)视为一个,错误,{{ 1}}。
我就是这么写的。
typedef enum{
type0 = 0,type1,type2
} my_values;
/* Here bool_type0() and bool_type1() are outside functions which return bool values */
my_values get_type(void)
{
my_values ret_val = type2;
if (bool_type0())
{
ret_val = type0;
}
else if (bool_type1())
{
ret_val = type1;
}
else
{
/* no need,type2 by default */
}
return ret_val;
}
function1 ()
{
my_values type_value = get_type();
if((type_value == type0) || (type_value == type1 ))
{
//update the logic
}
else
{
//update the logic
}
}
,
很可能是您的 linter 报告的误报。
在黑暗中的一些猜测让 linter 高兴。
- 尝试将三元的所有元素强制为 uint8:
将您的宏定义为:
#define get_type() (bool_type0() ? (uint8)type0 : bool_type1() ? (uint8)type1 : (uint8)type2)
- 可能是枚举声明中的
=0
把它扔掉了。尝试在没有它的情况下声明枚举:
这个:
typedef enum{
type0,// should default to 0
type1,type2
}my_values;
或所有显式:
typedef enum{
type0 = 0,type1 = 1,type2 = 2
}my_values;
- 最后,我很惊讶您没有收到关于
function1
没有明确返回类型的警告。我想知道您的函数定义中缺少指定的返回类型是否会导致 linter 关闭。将其明确标记为具有 void 返回类型:
试试这个:
void function1()
{
....