在 AND 和比较时进行符号转换

Sign conversion when ANDing and comparing

本文关键字:符号 转换 AND 比较      更新时间:2023-10-16

我有以下代码:

const uint8_t HEADER_SIZE = 0x08;
std::vector<uint8_t> a, b;
uint8_t x;
/* populate 'a', 'b'. Set 'x' */
for ( uint8_t i = 0; i < HEADER_SIZE; ++i )
{
    // The if statement (specifically the AND): Conversion to 'unsigned int' from 'int' may change the sign of the result [-Wsign-conversion]
    if ( x != ( a[i + HEADER_SIZE] & b[i] ) )
    {
         /* ... */
         break;
    }
}

我尝试投射几乎所有内容,但我似乎无法弄清楚为什么一个简单的 AND 会导致此警告。这两个变量都是无符号的。有什么想法吗?

a[i + HEADER_SIZE]b[i] 都将提升为 int,因为尽管它们都是无符号类型,但它们比 int 更窄的类型。所有较窄的整数类型都将提升为 int(如果int可以表示要升级的类型的所有值)或unsigned int用于所有内置算术运算。

将所有操作数显式转换为unsigned int应该使警告静音:

unsigned int a_dash = a[i + HEADER_+SIZE];
unsigned int b_dash = b[i];
unsigned int x_dash = x;
if (x_dash != (a_dash & b_dash))
{ // ...

你的uint8_t在被&一起之前被提升为int。然后int被比作x,这仍然是uint8_t。同样的事情发生在i + HEADER_SIZE.将结果转换回uint8_t应该会消除警告。

x != uint8_t(a[uint8_t(i + HEADER_SIZE)] & b[i])

问题出在索引上,请尝试:

_a = a[i + HEADER_SIZE];
_b = b[i];
if ( x != (_a & _b) )

您将看到问题出在_a = ...线。这是因为添加 i 和 HEADER_SIZE 会导致从 uint8_t 升级到 int。