为什么C++逐位AND运算符在不同大小的操作数中表现为这样
Why does the C++ bitwise AND operator behave like this with different-sized operands?
我很好奇在使用互补operator ~
移除位时,类型大小是否是一个因素,最终得到了一个奇怪的结果:
uint64_t x = 0xccccccccccccccccUL;
uint8_t y = 10;
auto z = ~y; // Debugger calls z an 'int' with value of 0xfffffff5
x &= z;
// x is now the correct value: 0xccccccccccccccc4
operator &
如何返回大于任意一个操作数的值?
下面的例子让我更加困惑,因为它看起来是相同的逻辑,但产生了不同的结果:
uint64_t x = 0xccccccccccccccccUL;
x &= 0xfffffff5;
// Now x is 0x00000000ccccccc4
这是怎么解释的?不管类型大小/符号如何,使用x &= ~y
删除位实际上安全吗?
您正在执行两个加宽操作。第一个是~
,它(像任何算术运算符一样(执行标准的"整数提升"。在这种情况下,由于源类型(uint8_t
(的所有值都可以放在int
中,所以这就是执行的提升。正如您所注意到的,z
被推导为具有类型int
。
第二个加宽操作是&=
,在这种情况下它等效于x = x & z
。uint64_t
不适合int
或unsigned int
,甚至不适合int64_t
,但uint64_t
和int
都适合uint64_t
,所以这是所选的类型。加宽(有符号的(int
涉及符号扩展,所以这就是额外比特的来源。
要回答您的最后一个问题,否,如果y
具有签名类型或比x
窄,则使用x &= ~y
来清除位是不安全的。有关这方面的更多信息,请参阅本文,但最重要的是,如果可能出现扩大的升级,请确保将~var
转换为预期的unsigned类型。如果您使用uint8_t
而不是auto
作为z
,您就不会遇到这个问题。
相关文章:
- 控制允许动态运行c++的并发操作数
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- 错误 C2679:二进制"<<":未找到采用类型 'std::string_view' 的右侧操作数的运算符(或者没有可接受的转换)
- BoostPython and CMake
- C++ 带有向量的 IF 计算操作数
- 是否所有C++运算符都接受操作数?
- OpenSSL BIO and SSL_read
- 一元*运算符的操作数是否期望一个 prvalue
- 与'operator='不匹配(操作数类型'String'且"void")
- Gurobi GRBModel and GRBmodel in C++
- 不正确的操作数类型 MSVC
- C2678 二进制 '==':未找到采用 'Card' 类型左操作数的运算符(或者没有可接受的转换)
- 错误:类型"double()"和"double()"的操作数无效到二进制&quo
- 我的运算符重载是否有效<<(流插入)左操作数不是 ostream
- 没有运算符"="与这些操作数匹配,JUCE 窗口演示应用程序
- 如果我在指针中使用 ++ 操作数,我的值就会出错