A signed& cannot be initialized from an unsigned& (and vice versa), but strict aliasing rules allow to read/write a signed object through an unsigned& (and vice versa), see C++20 standard [basic.lval]#11.2. This theoretically could be used in compiler optimizations, if the as-if rule is not violated.
Example 1. If I am correct, f could be implemented by just a jump to foo:
void foo(const unsigned& u);
void f(const signed& par)
{
foo(par);
}
But all compilers load par to a register, store the register on the stack, and pass the stack location to foo. Live demo.
Example 2. Similarly I think g1 and g2 could point to the same memory location:
const signed& g1 = 1;
const unsigned& g2 = g1;
But compilers tend to allocate two different locations. Live demo.
Question. Why is that? Isn't it a missed opportunity for optimization?