bool 类型的按位运算和逻辑运算相同吗?

alf*_*lfC 2 c++ boolean bitwise-operators logical-operators

C++ 具有适用于真/假值的逻辑运算 、、!a。并且它具有按位运算,适用于所有(整数?)类型,, , , , ( , )。与就地变异运算符一起使用 、、、( 、)。a && ba || b~aa & ba | ba ^ ba << Na >> Na &= ba |= ba ^= ba <<= ba >>= b

令我困惑的是,按位运算可能会作用于bool根本不属于真/假值的部分。甚至进行不必要的位操作。我想最后一个事实使得按位移位未定义bool,这让我怀疑所有按位运算是否都有效。

那么,这些对于 bool 类型等效吗?~a == !a, a && b == a & b, a || b == a | b?

由于某种原因(这里不会提出疑问),没有“就地”逻辑变异运算符(即a &&= b, a ||= b)。

这引发了这些问题,这些其他按位运算对布尔本身有效吗?和总是分别等于和a &= b?**(没有“就地”异或?)a |= ba = a && ba = a || ba = a ^ b

一些例子: https: //godbolt.org/z/hcccG8c9o

use*_*522 5

(为简单起见,我将假设 C++20,即整数类型的二进制补码表示形式。从技术上讲,我所写的内容可能不适用于 C++20 之前的所有理论上可能的整数类型一致表示形式。)

令我困惑的是,按位运算可能作用于完全不属于真/假值的 bool 位。

内置的按位运算首先对其操作数应用通常的算术转换。对于暗示整型提升的整型操作数:转换等级低于 of 的操作数int将转换为int第一个(或者,如果不能容纳原始类型的所有值,unsigned int则转换为更高等级的整型类型)。int

促销始终保持原始值不变。在 的情况下booltrue映射到1false0。因此,提升后的结果将设置或取消设置其最低有效位,而所有其他位均未设置。而且,总是至少有15这样的位,因为int必须至少有 16 位宽。

结果~a == !a总是错误的。~将设置这些附加位,而提升则!a不会。然而bool(~a) == bool(!a)true仅当ais时false,因为附加位设置bool(~a)总是true

a && b == a & b&始终为真,因为应用时附加位将为零。

a || b == a | b始终为真,因为额外的位将再次保持为零。

但是,如果ab是实际表达式,则还有另一个区别,即逻辑运算符会短路求值,而按位运算符则不会。因此,副作用可能会有所不同。

此外,逻辑运算符的结果将是 a bool,而按位运算符的结果将是 a int。因此它们不可互换,因为它们可能会影响使用其结果的重载解析。

此外,这仅适用于内置运算符。如果涉及任何重载的运算符,则没有任何保证。