Barry even explains, the transmutation is outlawed during compile time in C++. They could remove this prohibition but they did not.
Notice that e.g. Rust doesn't prohibit compile time transmutation, the provided core::mem::transmute literally does this operation, and it's const. The result is - as with similar situations in C++ - that if at compile time that's a 2 the compilation fails, 2 is not a boolean. You don't need all this bother because Rust's type system is better so Option<bool> already does have the same size as bool, but that's beside the point.
The whole problem only arises because accessing the union member as a character is allowed at runtime, but disallowed in constexpr. If that restriction were relaxed to be the same in both cases, the entire motivating problem would disappear...
Notice that e.g. Rust doesn't prohibit compile time transmutation, the provided core::mem::transmute literally does this operation, and it's const. The result is - as with similar situations in C++ - that if at compile time that's a 2 the compilation fails, 2 is not a boolean. You don't need all this bother because Rust's type system is better so Option<bool> already does have the same size as bool, but that's beside the point.