【问题标题】:Sign conversion when ANDing and comparingANDing和比较时的符号转换
【发布时间】:2012-10-01 14:54:23
【问题描述】:

我有以下代码:

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 会导致此警告。两个变量都是无符号的。有什么想法吗?

【问题讨论】:

  • uint8_t 类型的对象的值(假设存在uint8_t,这不是必需的)将始终不变地适合int,因此警告是无害的。

标签: c++ gcc casting unsigned-char


【解决方案1】:

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))
{ // ...

【讨论】:

    【解决方案2】:

    您的uint8_t 会在被&amp; 合并之前升级为int。然后将intx 进行比较,后者仍然是uint8_ti + HEADER_SIZE 也会发生同样的事情。将结果转换回uint8_t 应该可以消除警告。

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

    【讨论】:

      【解决方案3】:

      问题出在索引上,试试:

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

      您会看到问题出在 _a = ... 行。这是因为 i 和 HEADER_SIZE 的添加导致了从 uint8_t 到 int 的提升。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多