I don't have any references for that off hand. But, take a look at the source code of the EEPROM.h library for AVR processors. It uses C++ References extensively and it would be extremely clumsy to do the same thing with pointers.
I will look. But extreme clumsiness is different to "only a Reference will work".
I understand that ultimately code runs on processors, and languages afford means to make clear what we want machines to do.
And we are limited to what can be computed no matter how we express the algorithms.
I will seek to understand why taking an address and passing it by value from the caller, and dereferencing that pointer in a called function is not entirely adequate, that is to say just how clumsy can it get?
Following that line of thought through Reductio ad absurdum leads to the conclusion that the only programming language you ever need is machine code writen in binary.
C++ inherited pointers from C, so I couldn't remove them without causing serious compatibility problems. References are useful for several things, but the direct reason I introduced them in C++ was to support operator overloading. For example:
void f1(const complex* x, const complex* y) // without references
{
complex z = *x+*y; // ugly
// ...
}
void f2(const complex& x, const complex& y) // with references
{
complex z = x+y; // better
// ...
}
More generally, if you want to have both the functionality of pointers and the functionality of references, you need either two different types (as in C++) or two different sets of operations on a single type. For example, with a single type you need both an operation to assign to the object referred to and an operation to assign to the reference/pointer. This can be done using separate operators (as in Simula). For example:
Ref<My_type> r :- new My_type;
r := 7; // assign to object
r :- new My_type; // assign to reference
Alternatively, you could rely on type checking (overloading).For example:
Ref<My_type> r = new My_type;
r = 7; // assign to object
r = new My_type; // assign to reference