May one convert a char
with the value not \0
and not \1
into bool
using std::bit_cast
? And if yes, what will the value of the resulting bool
: true
or false
?
For example,
#include <bit>
constexpr bool x = [] {
return std::bit_cast<bool>('\2');
}();
int main() {
return x;
}
This program returns 2
in EDG and MSVC, 0
in GCC. And only Clang rejects it with the error:
<source>:3:16: error: constexpr variable 'x' must be initialized by a constant expression
/opt/compiler-explorer/clang-20.1.0/bin/../include/c++/v1/__bit/bit_cast.h:37:10: note: value 2 cannot be represented in type 'bool'
Online demo: https://gcc.godbolt.org/z/P6xPPn5Ez
Which implementation is correct here?
The relevant section is [bit.cast]:
For the result and each object created within it, if there is no value of the object's type corresponding to the value representation produced, the behavior is undefined.
One can determine if there exist padding bits using std::has_unique_object_representations
. If there are no padding bits, the object representation and the value representation are the same, and if a value is produced is not valid for that type, we have UB.
constexpr
often helps due to the prohibition that language UB is disallowed. Specifically, that is [expr.const]:
an operation that would have undefined or erroneous behavior as specified in [intro] through [cpp]
The UB here is not included.
Therefore, assuming no padding bits, the original program is UB. All 3 compilers are correct.