C++中对布尔值进行按位取反操作会产生令人困惑的结果。1根据C++标准([conv.bool]),转换到bool类型时,零值转为false,非零值转为true。1当对true执行按位取反操作时,true首先被提升为int类型(值为1),其补码为-2,再转换回bool后仍为true。1这种反直觉的现象源于整数提升的强制性——小于int的整数类型在位运算中必然被提升到int进行操作。1
不同编译器在处理这类操作时表现不一。1GCC编译器存在长期一致性漏洞,在处理enum class boolean : bool中的~boolean::TRUE时会错误地评估为boolean::FALSE,而Clang和MSVC则按标准正确评估所有四种补码和转换组合的结果为true。1此外,对于无固定底层类型的非作用域枚举,情况更加复杂。1这类枚举的有效值范围为M宽度整数,其中M为表示所有枚举子所需的最小位数,将位运算结果转换回此类枚举可能引发未定义行为,特别是当转换值超出枚举的有效范围时。1浮点数转换为bool型枚举时,GCC和Clang的行为与标准规范不符,可能产生越界的比特模式。1
A technical analysis on Hacker News explores counterintuitive behavior in C++ bitwise operations, particularly how integer promotion affects boolean and enumeration types 1. The investigation centers on the P4313 standards proposal, which seeks to add enumeration bitmask operations for C++26, and reveals how the bitwise NOT operator applied to true can unexpectedly remain true after type conversion 1.
According to the C++ standard, when converting to bool, zero values become false while any non-zero value becomes true 1. Integer promotion is mandatory in C++, meaning integers smaller than int are automatically promoted to int before bitwise operations occur 1. When true undergoes this process, it is promoted to the integer value 1, whose bitwise complement equals -2; when this result converts back to bool, it evaluates to true due to its non-zero value 1.
The analysis reveals significant compiler inconsistencies in handling these operations. GCC exhibits a long-standing anomaly where ~boolean::TRUE in an enum class boolean : bool evaluates to boolean::FALSE, deviating from the standard 1. By contrast, Clang and MSVC correctly evaluate all four combinations of bitwise complement and type conversion according to specification 1.
Unscoped enumerations without a fixed underlying type can trigger undefined behavior when bitwise operation results exceed the enumeration's valid range, as the valid value range is determined by an M-width integer where M represents the minimum number of bits needed to represent all enumerators 1. Further complications arise when converting floating-point numbers to bool-type enumerations, where GCC and Clang produce results inconsistent with the standard, potentially generating out-of-bounds bit patterns 1.
评论
还没有评论,欢迎留下第一条。