LHS和RHS变量都是uint8_t变量,但是该问题报告为“从int转换为unsigned char”。我不明白这怎么可能是个问题?
同样适用于8位数字
两个问题中列出的所有变量均为uint8_t
问题1)
CID 147563(第2个,共2个):违反编码标准(CERT INT31-C)3。 cert_violation:在不检查其值的情况下将(uint8_t)apX_compY_bitmask从int强制转换为unsigned char可能会导致数据丢失或解释错误。全局变量
/* AP_X_Flash_Component_Y_Authenticated */
static uint8_t AP_component_require_auth;
//Local variable:
uint8_t apX_compY_bitmask = 0u, port;
// other operations
AP_component_require_auth |= (uint8_t)apX_compY_bitmask;
问题2)
CID 148170(#1 of 1):违反编码标准(CERT INT31-C)5。 cert_violation:在不检查其值的情况下将major_revision >> 3从int转换为unsigned char可能会导致数据丢失或解释错误。
函数参数:
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
或unsigned 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;
}
输出(int
为32位)是:
sizeof(a) = 1
sizeof(b) = 1
sizeof(a | b) = 4
sizeof((uint8_t)(a | b)) = 1
sizeof(a >> 3) = 4
sizeof((uint8_t)(a >> 3)) = 1
所以在第一种情况下:
AP_component_require_auth |= (uint8_t)apX_compY_bitmask;
uint8_t
强制转换没有任何作用,因为它已经是该类型,并且肯定不会破坏隐式转换。
我不熟悉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
或相等/较大的整数类型。
Coverity警告简洁明了;如果直接使用它正在执行的标准,它会更加明确,并提供示例和解决方案:https://wiki.sei.cmu.edu/confluence/display/c/INT31-C.+Ensure+that+integer+conversions+do+not+result+in+lost+or+misinterpreted+data