取二进制值01010101b,即0x55或85.按位不应用8位表示应产生10101010b,即0xAA或170.
但是,我无法在C中重现上述内容.以下简单断言失败.
assert(static_cast<unsigned char>(0xAAu) == ~static_cast<unsigned char>(0x55u));
我用以下代码打印了0x55,0xAA和~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位整数上运行.这是为什么?
我应用了另一个测试来查看〜运算符返回的类型.事实证明,在unsigned char输入上是int:
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从~0x55产生0xAA?
解决方法
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 […]
整体促销活动将在4.5节整体促销活动中介绍,并说:
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;
为了完整性,要看到unsigned char rank小于int的等级,我们可以转到4.13整数转换等级,它表示:
The rank of a signed integer type shall be greater than the rank of
any signed integer type with a smaller size.
和:
The rank of char shall equal the rank of signed char and unsigned
char.
一种解决方案是将结果分配给unsigned char,这是安全的,因为您不必担心有符号整数溢出.
正如Ben Voigt所指出的,它将符合一个系统,其中sizeof(int)== 1和CHAR_BIT> = 32.在这种情况下,unsigned char的等级不应小于int,因此促销将是unsigned int .我们不知道实际发生的任何系统.