c++booleanlanguage-lawyerc++20bit-cast

Can any char be converted in bool using std::bit_cast?


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?


Solution

  • 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.