0

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

这同样适用于 8 位数字

两个问题中列出的所有变量都是 uint8_t

问题 1)

CID 147563 (#2 of 2): Coding standard violation (CERT INT31-C)3. cert_violation: 
Casting (uint8_t)apX_compY_bitmask from int to unsigned char without checking its 
value may result in lost or misinterpreted data.

/* 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): Coding standard violation (CERT INT31-C)5. cert_violation: 
Casting major_revision >> 3 from int to unsigned char without checking its 
value may result in lost or misinterpreted data.

函数参数:

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;
4

1 回答 1

2

要了解导致警告的原因,您必须了解(或至少了解)C 语言有些晦涩,有时甚至令人惊讶的类型提升规则。

C 位和算术运算符对intorunsigned 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;
}

输出(其中int32 位)为:

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

这两种情况下的问题都是将int大小类型分配给uint8_t. 虽然第一个警告有点令人困惑 - 可能是由于使用|=- 阻止它呈现隐式转换表达式;如果没有我认为的不必要的演员表,你应该得到同样的错误。我熟悉的静态分析工具会这样说:

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

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

Coverity 警告简洁明了;如果您直接查看它正在执行的标准,它会更加明确并提供基本原理、示例和解决方案: https ://wiki.sei.cmu.edu/confluence/display/c/INT31-C.+Ensure+that +整数+转换+做+不+结果+在+丢失+或+误解+数据

于 2020-04-22T17:05:52.640 回答