问题描述
当对小于int
的算术类型执行按位运算时,它会自动提升为int
。
std::uint8_t a = 42;
auto b = a | 0x0f;
// b will be of type int
我无法确定此次促销期间到底发生了什么,特别是因为它正在从无符号整数转换为有符号整数。 a
的数值会保持一致,从而可能会更改二进制表示形式吗?还是二进制表示形式保持一致,可能会导致数值不同?
是否有理由将值提升为int
而不是unsigned int
?后者不会引起任何这种混乱。
解决方法
提升后,整数具有相同的值。提升后的类型必须首先能够存储源类型的所有值(并且可能更多),才能做到这一点。特别是,这意味着提升后无符号值将永远不会为负,并且如果int
太小,则提升后的类型可能是unsigned int
。但是请注意,std::uint8_t
始终会足够大,因此将始终提升为int
。
当有符号整数上发生整数提升时,负值的“二进制表示形式”将被符号扩展(大于1s)。例如,使用std::int8_t a = -1;
,a & 0b100000000 != 0
,即使二进制表示形式仅为0b11111111
。但这不会发生在无符号值或有符号正值上。
升级后,对象表示形式(当您将其memcpy转换为char数组时)可能会更改。在带符号的情况下很容易看到这种情况,但是在无符号的情况下,由于字节顺序,字节的顺序可能不同。
,当对小于int的算术类型执行按位运算时,它会自动提升为int。
正确的 1 。同样,这适用于所有算术运算。不只是按位操作。
请问保持一致的数值
是的
可能会更改二进制表示形式吗?
位取决于您对二进制表示形式的期望。每个位将按照重要性顺序具有与相应原始位相同的值。但是字节的存储顺序将在小端系统上改变。
是否有理由将该值提升为int
是的。在this答案中引用的ANSI C基本原理中解释了这种设计选择。简而言之,这使价值在所有促销活动中保持一致。
1 从技术上讲,它可以在某些条件下的某些系统上提升为unsigned int。更具体地说,将较低等级的整数类型提升为int或unsigned int。 Char和short的大小比int低,无论它们是较小的还是相同的大小。如果原始值不能用int类型表示,则将其提升为unsigned int。在unsigned char和/或unsigned short与int大小相同的系统上可能会发生这种情况。