Embedded Coverity静态分析将字符或数字视为C中的int

Embedded Coverity静态分析将字符或数字视为C中的int,embedded,coding-style,static-analysis,coverity,xc32,Embedded,Coding Style,Static Analysis,Coverity,Xc32,LHS和RHS变量都是uint8_t变量,但问题被报告为“从int转换为unsigned char”。我不明白这怎么会是个问题 这同样适用于8位数字 两期中列出的所有变量均为uint8\t 问题1) 问题2) 函数参数: void sb_rollb_prot_AP_FW_in_use_update(uint8_t img_idx, uint8_t port, uint8_t major_revision, bool primary_image) //Local Variable uint8_t

LHS和RHS变量都是uint8_t变量,但问题被报告为“从int转换为unsigned char”。我不明白这怎么会是个问题

这同样适用于8位数字

两期中列出的所有变量均为uint8\t

问题1)

问题2)

函数参数:

void sb_rollb_prot_AP_FW_in_use_update(uint8_t img_idx, uint8_t port, uint8_t major_revision, bool primary_image)

//Local Variable
uint8_t x_loc, y_loc;
y_loc = major_revision >> 3;

要理解是什么导致了这个警告,你必须理解(或者至少要知道)C的一些晦涩的,有时令人惊讶的类型提升规则

C位运算符和算术运算符对
int
无符号int
或更大类型进行操作,因此当使用较小类型的操作数时,会发生隐式提升:

以这个“实验”为例:

#include <stdint.h>
#include <stdio.h>

int main()
{
    uint8_t a ;
    uint8_t b ;

    printf( "sizeof(a) = %zu\n", sizeof(a) ) ;
    printf( "sizeof(b) = %zu\n", sizeof(b) ) ;
    printf( "sizeof(a | b) = %zu\n", sizeof(a | b) ) ;
    printf( "sizeof((uint8_t)(a | b)) = %zu\n", sizeof((uint8_t)(a | b)) ) ;
    printf( "sizeof(a >> 3) = %zu\n", sizeof(a >> 3) ) ;
    printf( "sizeof((uint8_t)(a >> 3)) = %zu\n", sizeof((uint8_t)(a >> 3)) ) ;


    return 0;
}
因此,在第一种情况下:

AP_component_require_auth |= (uint8_t)apX_compY_bitmask;
uint8\u t
cast没有任何作用,因为它已经是那种类型,并且肯定不会破坏隐式转换

我不熟悉CERT-C或Coverity,但在我使用过的类似工具中,可以使用隐式转换来断言该表达式是故意的:

AP_component_require_auth = (uint_8_t)(AP_component_require_auth | apX_compY_bitmask) ;

y_loc = (uint8_t)(major_revision >> 3) ;
如您所见,无法使用
|=
解决此问题,因为您无法在赋值之前强制转换
|
表达式的结果

但是,通常最好保持类型一致性,避免隐式或显式转换,并使用
int
unsigned
或大小相等/更大的整数类型(如果没有强制理由使用较小的类型)

这两种情况下的问题都是将
int
大小的类型分配给
uint8\u t
。尽管第一个警告有点让人困惑——可能是因为使用了
|=
——阻止它呈现隐式强制转换表达式;我认为,你应该得到同样的错误,没有不必要的演员。我熟悉的静态分析工具会说:

赋值中向较小类型的隐式转换

在这两种情况下,我认为这一点更清楚


Coverity警告简明扼要;如果你直接去看它正在执行的标准,它会更加明确,并给出基本原理、示例和解决方案:

要理解是什么导致了警告,你必须理解(或至少要知道)C有些神秘,有时令人惊讶的类型提升规则

C位运算符和算术运算符对
int
无符号int
或更大类型进行操作,因此当使用较小类型的操作数时,会发生隐式提升:

以这个“实验”为例:

#include <stdint.h>
#include <stdio.h>

int main()
{
    uint8_t a ;
    uint8_t b ;

    printf( "sizeof(a) = %zu\n", sizeof(a) ) ;
    printf( "sizeof(b) = %zu\n", sizeof(b) ) ;
    printf( "sizeof(a | b) = %zu\n", sizeof(a | b) ) ;
    printf( "sizeof((uint8_t)(a | b)) = %zu\n", sizeof((uint8_t)(a | b)) ) ;
    printf( "sizeof(a >> 3) = %zu\n", sizeof(a >> 3) ) ;
    printf( "sizeof((uint8_t)(a >> 3)) = %zu\n", sizeof((uint8_t)(a >> 3)) ) ;


    return 0;
}
因此,在第一种情况下:

AP_component_require_auth |= (uint8_t)apX_compY_bitmask;
uint8\u t
cast没有任何作用,因为它已经是那种类型,并且肯定不会破坏隐式转换

我不熟悉CERT-C或Coverity,但在我使用过的类似工具中,可以使用隐式转换来断言该表达式是故意的:

AP_component_require_auth = (uint_8_t)(AP_component_require_auth | apX_compY_bitmask) ;

y_loc = (uint8_t)(major_revision >> 3) ;
如您所见,无法使用
|=
解决此问题,因为您无法在赋值之前强制转换
|
表达式的结果

但是,通常最好保持类型一致性,避免隐式或显式转换,并使用
int
unsigned
或大小相等/更大的整数类型(如果没有强制理由使用较小的类型)

这两种情况下的问题都是将
int
大小的类型分配给
uint8\u t
。尽管第一个警告有点让人困惑——可能是因为使用了
|=
——阻止它呈现隐式强制转换表达式;我认为,你应该得到同样的错误,没有不必要的演员。我熟悉的静态分析工具会说:

赋值中向较小类型的隐式转换

在这两种情况下,我认为这一点更清楚


Coverity警告简明扼要;如果你直接去看它正在执行的标准,它会更加明确,并给出基本原理、示例和解决方案:

你读过CERT规则了吗?你不能让一个静态分析器检查你不知道的编码标准的违反情况,那是非常危险的。这在网上是免费的。是的,有符号的
int
uint8_t
之间的大量隐式转换是危险的,最终会成为细微错误的来源。我甚至尝试为3(3u)添加u,问题仍然存在。@Lundin同样,我没有得到一点,你的意思是说我不能用Coverity来检查证书C规则…??我是说:你不明白的是上面提到的规则到底是什么?或者,如果你想让别人告诉你你的代码有什么问题,你需要发布代码,包括变量声明。我想他们关心的是你的两个例子中存在的问题<代码>AP_组件_require_auth|=(uint8_t)apX_compY_位掩码=
AP\u component\u require\u auth=AP\u component\u require\u auth(uint8\t)apX\u compY\u位掩码
其中
|
的两个操作数都隐式提升为
int
。在
主要修订版>>3中
,操作数
主要修订版
被隐式提升为
int
。您阅读了证书规则吗?你不能让一个静态分析器检查你不知道的编码标准的违反情况,那是非常危险的。这在网上是免费的。是的,有符号的
int
uint8_t
之间的大量隐式转换是危险的,最终会成为细微错误的来源。我甚至尝试为3(3u)添加u,问题仍然存在。@Lundin同样,我没有得到一点,你的意思是说我不能用Coverity来检查证书C规则…??我是说:你不明白的是上面提到的规则到底是什么?或者,如果你想让别人告诉你你的代码出了什么问题,你需要发布
AP_component_require_auth = (uint_8_t)(AP_component_require_auth | apX_compY_bitmask) ;

y_loc = (uint8_t)(major_revision >> 3) ;