C++ - Bit-wise not of uchar produces int

后端 未结 3 1783
感情败类
感情败类 2021-01-05 09:54

I am surprised by C++\'s behavior when applying bit-wise not to an unsigned char.

Take the binary value 01010101b, which is 0x55, or

相关标签:
3条回答
  • 2021-01-05 10:34

    The answer about integral promotion is correct.

    You can get the desired results by casting and NOTting in the right order:

    assert(static_cast<unsigned char>(0xAAu) == static_cast<unsigned char>(~0x55u));
    
    0 讨论(0)
  • 2021-01-05 10:38

    You can kind of "truncate" the leading 1's by assigning the result of ~0x55 to an unsigned char:

    #include <iostream>
    
    int main()
    {
        unsigned char input = 0x55;
        unsigned char output = ~input;
    
        std::cout << "input: " << (int)input << " output: " << (int)output << std::endl;
    
        return 0;
    }
    

    Result:

    input: 85 output: 170
    
    0 讨论(0)
  • 2021-01-05 10:41

    Integral promotions are performed on the operand of ~ we can see this by going to the draft C++ standard section 5.3.1 Unary operators which says (emphasis mine):

    The operand of ˜ shall have integral or unscoped enumeration type; the result is the one’s complement of its operand. Integral promotions are performed. The type of the result is the type of the promoted operand [...]

    and the integral promotions are covered in section 4.5 Integral promotions and say:

    A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type;

    For completeness, to see that unsigned char rank is less than the rank of int we can go to section 4.13 Integer conversion rank which says:

    The rank of a signed integer type shall be greater than the rank of any signed integer type with a smaller size.

    and:

    The rank of char shall equal the rank of signed char and unsigned char.

    One solution would be to assign the result to an unsigned char which, this is safe since you don't have to worry about signed integer overflow.

    As Ben Voigt points out it would compliant to have a system where sizeof (int) == 1 and CHAR_BIT >= 32. In which case the rank of unsigned char woudl not be less than int and therefore the promotion would be to unsigned int. We do not know of any systems that this actually occurs on.

    0 讨论(0)
提交回复
热议问题