3

While there are zillions of sources on clarifying the concept of references in C++, I'm trying to explain the concept of reference to someone who is familiar with pointers. In other words, I'm wondering whether the following semantic expression is ALWAYS true?

TYPE& == *(TYPE const *)
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • What is mean by ALWAYS correct? – Pranit Kothari Jan 12 '15 at 02:03
  • @PranitKothari under any circumstances and in any situations. –  Jan 12 '15 at 02:04
  • 3
    Those aren't anywhere *near* ALWAYS equivalent. For one, a const-pointer dereferences to a const object, *not* compatible with a non-const reference, so it isn't even *legal*. What made you decide to inject `const` into this? – WhozCraig Jan 12 '15 at 02:05
  • 4
    `TYPE& == *(TYPE * const)` would be closer to what I think you're trying to communicate. – WhozCraig Jan 12 '15 at 02:12
  • See [What are the differences between a pointer variable and a reference variable in C++?](http://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in) – David G Jan 12 '15 at 02:13
  • The best I have found to explain references is that they are an *alias* to the object, a new name for it. Now, depending on context, it may be implemented underneath by holding the address of the aliased object (and thus similar to a pointer) or not, but I find it simpler to explain if you stay at the higher level: a new name for an existing thing. – David Rodríguez - dribeas Jan 12 '15 at 04:58

5 Answers5

2

The expression

TYPE& == *(TYPE const *)

looks a bit of domain error as TYPE& is a type while *(TYPE const*) looks like an expression applied to a type. At the very least, the right hand side should be const pointer rather than a pointer to const, i.e.:

A TYPE& behaves like an auto-dereferenced immutable pointer, something like *(TYPE* const) with the implicit constraint that the pointer cannot be null.

The compiler does recognize references and in some cases, namely when binding temporaries to a reference to a const object (T const&) at function scope: the life-time of the temporary gets expanded until the reference goes out of scope! For example:

{
    std::string const& s = std::string("longer lived");
    // the original temporary created above still lives
}   // <-- ... and gets destroyed when s goes out of scope here

Another major difference between pointers and references are semantics when it comes to operator overloading: pointers are consider built-in types and operators only involving built-in types cannot be overloaded. A reference of type T& behaves like a T object, i.e., overloaded operators for T& are considered. That is, while the a T& is identical to using a T* const from a representation point of view, the compiler understands the difference and treats the entities differently on a semantic level.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
0

Yes, if you disassemble C++ code in Visual Studio, reference is nothing but const pointer. So both are almost equivalent.

But be aware, you cannot assign NULL (0/nullptr) to reference.

Pranit Kothari
  • 9,721
  • 10
  • 61
  • 137
  • 3
    Note: the OP's pseudo is not a `const` pointer; it is a pointer to `const`. There is a *big* difference. The former disallows modification of the *pointer*. The latter disallows modification of the *object* it points to. – WhozCraig Jan 12 '15 at 02:16
  • @WhozCraig, spot on, OP probably wants `TYPE& == *(TYPE * const)`, but even in this case references are not really the same, as this answer points out: cannot initialize with NULL a reference, but can initialize to NULL a `const` pointer. – vsoftco Jan 12 '15 at 02:40
  • The output of one compiler (or indeed, all) isn't conclusive for a language question. – Neil Kirk Jan 12 '15 at 03:11
0

Probably the best way to explain references is to use Stroustroup's example showing how they allow creating functions that replace macros, something that would not be possible without references.

user3344003
  • 20,574
  • 3
  • 26
  • 62
0

The stated possible type equivalence TYPE& == *(TYPE const *) does not make literal sense since the right hand side isn't a type, and since it's about a pointer to const instead of a const pointer.

However, considering the thing in an associative sense, one can imagine a rewrite rule where a reference declaration

T& r = o;

is rewritten as

T* const __p = &o;

and where every use of r is then rewritten as

(*__p)

Except for handling of the case where o is an rvalue expression it explains most and perhaps all practical properties of references.

However, as the relevant FAQ item “How can you reseat a reference to make it refer to a different object?” states,

please don't confuse references with pointers; they're very different from the programmer's standpoint

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
0

One of the ways it differs, is that you cannot take the address of a reference,
but you can take the address of a pointer. Since you can take the address of a
pointer, it must have storage. However, references do not have to have storage
(they are defined in the standard as aliases), and as often the compiler can,
they will in fact not have storage.

sp2danny
  • 7,488
  • 3
  • 31
  • 53
  • Applying the address-of operator to a reference and to the result of using `*` on a pointer has exactly the same effect -- the address of the target. Both references and pointers need equal amounts of storage because they contain the same amount of information, until the compiler can prove that information can be obtained other ways, and then no storage is needed. – Ben Voigt Jan 12 '15 at 03:01
  • Once the compiler gets to the low-level code, it doesn't care about the difference between references and pointers any more. If a compiler can omit the space of a pointer without changing the behavior, it's allowed to do so. – Neil Kirk Jan 12 '15 at 03:04