Consider: #include <bit> void f(); auto const p1 = &f; auto const p2 = std::bit_cast<void(*)()>(&f); bool a() { return p1 == p2; } The code emitted for `a` should be the same as-if `return true;` but the usage of a "no-op" `std::bit_cast` muddies the waters and the compiler generates: a(): cmp QWORD PTR p2[rip], OFFSET FLAT:_Z1fv sete al ret FWIW: The following changes make the compiler to generate more efficient code: 1. Move `p1` and `p2` inside the body of `a`. 2. Replace `std::bit_cast` with `static_cast`. 3. Remove the cast altogether. Things get terribly worse if `p1` and `p2` are made `static` and moved inside the body of `a`. Given that the compiler can get confused by a "no-op" `std::bit_cast`, I wonder if it would do the same for more interesting code than this toy example. https://godbolt.org/z/daWe5Yod8
void f(); static auto const p2 = __builtin_bit_cast(void(*)(), (&f)); Even causes the front-end to emit a dynamic initializer for p2. There is definitely 2 issues here, one for the above and one for the original code. Note bit_cast is not a const expression due to being a pointer type and that is what causes the front-end to emit dynamic initializer. But I wonder if the front-end could try to do it without the dynamic initializer. Anyways confirmed. Note there is another bug about converting dynamic initializers to static initializers (PR 4131 and PR 102876).