In C++, if you have a variable
char c;
and an initialiser
char& p = c;
followed by an assignment
p = c;
what is the semantics of the initializer, and what is the semantics of
the assignment? Once you figure that out, you know why reassigning the
address of an object to a reference is problematic, and then it will
be obvious why pointers in C++ and C don't have that problem at all.
(Aside from the Undefined Behavior due to reading an uninit object, if
the declaration of c, and thus also p, is block-scope? <G>)
There are easy enough ways to disambiguate the operations.
In Fortran, 'pointer' uses are implicitly dereferenced,
and a different syntax (operator?) is used for reseating.
P = expr changes the target; P => loc changes the pointer.
(In former-Tandem's SIL TAL, now pTAL, pointers are derefed;
P := val changes target and @P := loc changes pointer.)
In Ada, 'access' type is usually implicitly derefed (and can be
explicitly if you prefer), and overload resolution includes expected
type (unlike C++). P = val or P.all = val changes target and P = loc
changes pointer. 'renames' can create an unreseatable reference.
Algol 68 implicitly derefs 'ref' and chooses target or pointer based
on type (except in some weird cases IIRC) for mutable 'ref', and has a
slightly different syntax to create an immutable (but still derefed)
ref. Both similarly call niladic functions without an empty arglist.
C++ refs are unreseatable because BS chose so. It might be addressed
in D&E; my copy is inaccessible for now. AFAIK there hasn't been any
serious desire to change it, because it's not a problem: you can still
do anything reasonable with only minor circumlocutions, such as using
a pointer or an extra local reference (or a few).