This is a classical example of strict aliasing violation:
std::uint32_t foo(float* f, std::uint32_t* i) {
    *i = 1;
    *f = 2;
    return *i;
}
int main() {
    std::uint32_t i = 3;
    foo(reinterpret_cast<float*>(&i), &i);
}
But suppose we add the second reinterpret_cast:
static_assert(alignof(float) == alignof(std::uint32_t));
std::uint32_t foo(float* f, std::uint32_t* i) {
    *i = 1;
    *reinterpret_cast<std::uint32_t*>(f) = 2;
    return *i;
}
int main() {
    std::uint32_t i = 3;
    std::uint32_t j = foo(reinterpret_cast<float*>(&i), &i);
    assert(j == 2);
}
Is this code correct (doesn't invoke undefined behaviour)?
The standard [expr.reinterpret.cast] reads:
Note: Converting a prvalue of type “pointer to
T1” to the type “pointer toT2” (whereT1andT2are object types and where the alignment requirements ofT2are no stricter than those ofT1) and back to its original type yields the original pointer value.
We use the original pointer value of type std::uint32_t* to access the lvalue of type std::uint32_t.
Both GCC and Clang generate correct assembly code when optimization is turned on:
foo(float*, unsigned int*):
        mov     dword ptr [rsi], 1
        mov     dword ptr [rdi], 2
        mov     eax, dword ptr [rsi]
        ret
 
    