C ++ - 不是uchar的比特产生int

时间:2014-09-29 13:37:13

标签: c++ bit-manipulation integer-promotion

我很惊讶C ++在按位时不应用于无符号字符时的行为。

获取二进制值01010101b,即0x5585。不按位比特应用8位表示应该产生10101010b,即0xAA170

但是,我无法在C ++中重现上述内容。以下简单断言失败。

assert(static_cast<unsigned char>(0xAAu) == ~static_cast<unsigned char>(0x55u));

我使用以下代码打印了0x550xAA~0x55(作为uchar)的值。并且它揭示了按位并不能达到我的预期。

std::cout << "--> 0x55: " << 0x55u << ", 0xAA: " << 0xAAu << ", ~0x55: "
     << static_cast<unsigned>(~static_cast<unsigned char>(0x55u)) << std::endl;

--> 0x55: 85, 0xAA: 170, ~0x55: 4294967210

~0x55打印的数字等于11111111111111111111111110101010b,这是32位按位而不是0x55。因此,即使我明确地将输入转换为~unsigned char运算符也在32位整数上运行。那是为什么?

我应用了另一个测试来查看~运算符返回的类型。在int输入上结果为unsigned char

template <class T>
struct Print;

// inside main()    
Print<decltype(~static_cast<unsigned char>(0x55))> dummy;

产生以下编译器错误,表明结果类型为int

error: implicit instantiation of undefined template 'Print<int>'
    Print<decltype(~static_cast<unsigned char>(0x55u))> dummy;

我做错了什么?或者,如何让C ++从0xAA生成~0x55

完整代码为here

3 个答案:

答案 0 :(得分:9)

~的操作数上执行整体促销活动我们可以通过转到draft C++ standard部分5.3.1 一元运算符来查看(强调我的):

  

〜的操作数应具有整数或无范围的枚举类型;该   结果是其操作数的补码。 整体促销   执行。结果的类型是提升的操作数的类型[...]

并在4.5 整体促销部分介绍了整体促销活动,并说:

  

除bool,char16_t,char32_t或之外的整数类型的prvalue   wchar_t,其整数转换等级(4.13)小于等级   如果int可以表示all,则int可以转换为int类型的prvalue   源类型的值;

为了完整性,要看到 unsigned char 等级小于 int 的等级,我们可以转到4.13 部分转换等级< / em>其中说:

  

有符号整数类型的等级应大于等级   任何带有较小尺寸的有符号整数类型。

  

char的等级应等于signed char和unsigned的等级   炭。

一种解决方案是将结果分配给 unsigned char ,这是安全的,因为您不必担心有符号整数溢出。

正如Ben Voigt所指出的,它将符合sizeof (int) == 1CHAR_BIT >= 32的系统。在这种情况下,unsigned char的等级woudl不小于int,因此促销将是unsigned int。我们不知道实际发生的任何系统。

答案 1 :(得分:2)

关于积分推广的答案是正确的。

您可以通过按正确的顺序进行投射和注释来获得所需的结果:

assert(static_cast<unsigned char>(0xAAu) == static_cast<unsigned char>(~0x55u));

答案 2 :(得分:1)

您可以通过将~0x55的结果分配给unsigned char来“截断”前导1:

#include <iostream>

int main()
{
    unsigned char input = 0x55;
    unsigned char output = ~input;

    std::cout << "input: " << (int)input << " output: " << (int)output << std::endl;

    return 0;
}

结果:

input: 85 output: 170