Pointers And References Are The Same Thing

Pointers And References Are The Same Thing (almost)

They are syntactically different, but semantically mean pretty much the same. Pretty much because in some systems they are decorated to provide checking.


Before any more editing is done to this page, someone should clarify (or probably split the discussion) depending on the programming language about which we talk (if any). Clearly, if we talk about ReferencesInCeePlusPlus? the following is the equivalent:

  T var;                      // T may be basic type or object
  T &ref = var;               // defining reference
  T *const ptr = &var;        // defining and initializing pointer
  .... ref ....               // effectively accessing object "var"
  .... *ptr ....;             // same for pointer
  ref = ...;                  // changing var (esp. if va is basic type)
  *ptr = ...;                 // same for pointer
  ref.method();               // calling method ("sending message")
  ptr->method();              // same for pointer
  .... ptr ....               // address of var
  .... &ref ....              // same for reference
  T *const nptr = 0;          // never compares equal to pointer
                              // pointing to an existing variable
  if (nptr == 0) ...          // check if pointer points to existing variable
  T &nref = (*(T *)0)         // deprecated but also see remark below
  if (&nref == 0) ...         // check if reference references existing variable
When I started with C++, for a few years I was of the opinion that references are guaranteed to point to an existing variable, which is of course not true for pointers. About 10 or 12 years ago I learned from the OWL manuals (Borland's Object Windows Library) that there is a method to create a new window. The PARENT window was given to the creating routine via a REFERENCE. As the top-level window of an application had no parent, you had to supply a "null reference" as shown above. (The OWL manual also showed the "trick" I used above to create such a beast like the "null reference".)

If we are talking about ReferencesInJava?, we effectively talk about something that would be implemented as a pointer in C++. All objects in Java are accessed "per reference", but differently from what C++ calls a "reference" an object reference in Java can refer to different objects during its lifetime. (BTW: The Java people seem very proud not having pointers in their language but they forgot one thing: To rename the NullPointerException to something different - because, if they have no pointers, so why ... - you see :-))

Not knowing much about the Smalltalk language I have the impression object access is much like in Java, so ReferencesInSmalltalk? are about the same as in Java, same probably for ReferencesInPython?, ReferencesInRuby? and some other languages that support the OO paradigma.

Finally, we could discuss ReferencesAsConcept?. As such I'd also make a big difference from PointersAsConcept?, but in the latter case the discussion should be aware of pointers coming in very different flavors: Untyped memory addresses like in assembler (more or less C/C++ "void *") or pointers with a given type and - in C/C++ - judicious use of cast operations (= very, very, VERY few - I mean it(!) - in some central places only) and following a sane set of rules (at a higher level than pure "guidelines" or "recommendations") let pointers conceptually work like references. (And - back to C++ - a so called "pointer to member" again is a very different beast.)

-- AnonymousDonor

Admittedly, references as provided in C++ are an incomplete concept, as references cannot be created nor destroyed from the heap (One can create and destroy references directly on the stack). For heap-based objects, one needs to create a pointer via new and recast it to a reference. Likewise to destroy the object, one needs to recast the reference to a pointer (or recover the pointer from some other storage location) and call delete. Both of these types of reference can lead to problems where the reference out lives the lifetime of the object (i.e., invalid references) or the object out lives the lifetime of the reference (memory leaks, wasted memory). Although C++ references do not fully eliminate memory management issues, they do tend to reduce the number of places where problems can arise. For that reason alone, I recommend use of references, but emphasize one must pay attention to the creation and deletion of objects relative to their use. -- WayneMack


Yes, and "PassByValue" is also a canard, because "we're passing the value of the pointer (or reference)."

From which language's perspective are you talking from? This sounds like Java ... but Java doesn't have pointers, only references. If you're talking about C++, you're dead wrong; see below. -- PaulChisholm


Okay, well, maybe I'm wrong, but here it goes: Pointers and references are not the same. A pointer implies that I am able to arbitrarily assign any memory address to it and that I may read and write from that memory address.

A pointer implies no such thing. Arbitrary virtual memory addresses (much less physical memory addresses) cannot be assigned to pointers in languages like C or C++ without causing UndefinedBehavior. Note that this is not just because UndefinedBehavior can be the result of accessing the intended memory address; there is no guarantee that an access to that address occurs at all. Particular implementations of these languages may allow casts between integers and pointers as if the integer referred to an address, but the semantics aren't defined by the language.

A reference, on the other hand, is a more abstract concept. It is fair to say, indeed, that a pointer can act like a reference, but that a reference cannot, in fact, act like a pointer. This, I realize, may seem like semantics, but it isn't. The fact that I can zero-write all of memory (or try, at least) with a pointer and cannot do the same thing with a reference is a fundamental difference.

I blame Java for all of the misunderstandings here. Assembler and C/C++ programmers (I hope) would never mistake these two for the same thing. -- JeffPanici

Oh, yeah, and there's more: a pointer can only point to memory, by definition. Programmers might say things like, "This pointer points to (or references) a BlahBlah struct or object", but it is just memory. A reference, being a higher-level concept, can refer to anything. The definition of reference, hence, is more flexible than a pointer from a language standpoint. I end my rant. -- JeffPanici again

It seems to me that an entity that (1) identifies an address in memory and (2) allows the contents of that address to be loaded and stored (whether we call such an entity a "pointer" or a "reference") is fundamentally not very different from an entity that (1) identifies a location on a disk and (2) allows the contents of that location to be loaded and stored. Further, the result of an attempt to load or store a memory address that is undefined or not existent is fundamentally not very different from an attempt to load or store a disk address that is undefined or nonexistent. Next, I argue that whether I use an integer or a symbol to select one of several offsets from a shared base, I am still performing fundamentally the same operation, and again it doesn't matter whether I'm doing that to memory or to a disk.

On the other hand, in languages with pointers - C and C++, for example, it IS possible to do arithmetic on the pointer - add some offset to it, for example - and then dereference it. This is, for me, a more fundamental difference. So perhaps it might be more accurate to say that ImmutablePointersAndReferencesAreTheSameThing?.

As I recall, pointers refer to a location in a physical space. A reference is a logical thing, that may be implemented as a pointer, but may not. It may be an associative key-value or some other synthetic index. So I might say "the reference to the foo object is implemented as a pointer into the shared memory segment". So pointers and references may be the same thing, but they don't have to be.


I think we've got too much into assembler versus java comparison. Untyped pointers (memory addresses) as in assembly and as in C with memset, memcpy and the likes, are a lower level construct, and I agree they are not references. However typed pointers, as in C++, Pascal, Ada '95 are conceptually the same thing with references. Except for the pointer arithmetic in C++ which is an unfortunate heritage from C. Whether a typed pointer is direct (contains the physical address of an object) or indirect it's another issue, but this is transparent to the programmer.

Maybe a standard definition of reference and pointer could help.


(*sigh*)

The only language I know of that has both pointers and references is C++.

The C++ compiler implements pointers and references similarly, but their semantics are very different! A pointer points to whatever address has been assigned to it most recently. A reference refers to a particular value, forever (well, for as long as the reference exists); it cannot be made to refer to something else.

Really, honestly, it was just precisely yesterday that an experienced C++ programmer said to me, "I've got two big data structures, and I don't want to copy them, so I have two references and I swap the references each time ..."

No, he didn't.

 Thing thing1, thing2;  // we have two things

Thing *p1, *p2; // we have two pointers to things

p1 = &thing1; // p1 now points to thing1 p2 = &thing2; // p2 now points to thing2

// now we swap what points to what p1 = &thing2; // p1 now points to thing2 p2 = &thing1; // p2 now points to thing1

// now we swap them back p1 = &thing1; // p1 now points to thing1 p2 = &thing2; // p2 now points to thing2

Thing &r1 = thing1, &r2 = thing2; // references

r1 = thing2; // the object r1 refers to, gets the value of thing2 (*p1) = thing2; // similar to the above statement; it's a copy!

Thing &r; // illegal; references must be initialized r = thing1; // too late!
Passing by pointer and passing by reference are different, too.

Exercise for the reader: distinguish between the following:

 char * p1 = "one";
 const char * p2 = "two";
 char const * p3 = "three";
 char * const p4 = "four";
 char const * const p5 = "five";
(ConstPointersExercise?)

-- PaulChisholm (who is not a PoorCppProgrammer? in any sense of the phrase, thank you very much, and who understands that using C++ involves trade-offs of productivity, safety, performance, portability, and "packageability")

How about: find something that you are able to solve by using references, but you aren't able to solve using pointers, and almost identical code (change only the initialization of a reference with an initialization of pointer, reference params with pointer params and x.something with y->something ? --CostinCozianu (ex- happy C++ programmer).

How about it? There's nothing you can do with references that you can't do with pointers; but the solution using references may be more readable to an experienced C++ programmer than the solution using pointers. (The inexperienced C++ programmer may be befuddled at a variable passed by non-const reference that gets changed during the function call.) Exception: C++ copy constructors are, by definition, defined in terms of references. There are things you can do with pointers, but not with references, such as "swapping pointers to two objects" as shown above. -- PaulChisholm

So to butt in, as I am not a C++ programmer, how would you swap references to two objects? Make two new references and use them? How would a linked list using references instead of pointers update things then? --anon

So const pointers as in { X x(...); X const *p= &x; { /*block_with_p*/ } } versus { X x(...); X &r=x; {/* block_with_r */ }}, and references are logically equivalent (aside the minor syntax difference). Agreed?

PointersAndReferencesAreTheSameThing in the sense that references are syntactic sugar for pointers that have some operations restricted. This is a Bad Thing. If something has reference semantics, it jolly well ought to have different syntax from something with value semantics. "The inexperienced C++ programmer may be befuddled at a variable passed by non-const reference that gets changed during the function call" -- and I don't blame them. Such code is inherently confusing and is poor style. -- PeterHartley (who didn't like references at all when a novice C++ coder, and, now a more experienced one, doesn't like non-const references at all)

References imply a persistence that pointers do not, i.e., pointers can be NULL or invalid. Pointers can also imply an array rather than a single instance, although thankfully I have not seen pointers used this way outside of char *. References are a way to indicate that a parameter is always expected to be valid, and if the caller is dereferencing a pointer, it is the caller's responsibility to ensure the validity of the pointer. That is why references, both const and non-const, should be your preferred style. As for what may befuddle an inexperienced programmer, almost any construct in any language can cause confusion. There is no need to single out references in C++. -- WayneMack

Wayne, try this in your compiler:

 void f(X&); 
 ...
 X *p= NULL;
 X &r= *p; //Should fail here at runtime, but it usually does not
 f(r);
I have yet to see an indication that a pointer parameter is expected to be invalid, while references, in spite of their generous intentions, can be as invalid as any pointer can be (the above is one of the many examples). The heart of the matter is that pointers and references are really redundant. And redundant features are bad in any language. Pointer arithmetic is another awful redundant feature, good only for writing ugly code. As much as I like C++, I have to admit that it has its large share of design problems. As a comparison Ada '95 deals with these issues a lot better. -- CostinCozianu

How is a null or an invalid reference created? It is only by assignment from an invalid pointer (or a change to a pointer after a reference is created) that causes an invalid reference. This provides a clear expectation of intent. If one sees the following prototype, there is no indication whether null is permitted. If null causes a failure, should we presume the calling function or the called function is incorrect?

 void Function1(Class1 * theObject);
Declaring the method as a reference, as follows, removes this ambiguity.

 void Function2(Class2 & theObject);
Having spent more than my fair share of time tracking down null pointers, especially null char * pointers, I will take any compiler provided assistance I can get. The fewer *s running around the program, the easier it is to find where something went awry. I can ignore the references and concentrate on the pointers to isolate the problem. -- WayneMack

[An aside on pointer arithmetic. Do you really prefer something like

  theObject = theObjectSet[theObjectIndex++]; 
over

  thObject = *theObjectSet++;
The latter is most certainly pointer arithmetic, but I believe it is much closer to the intent of "get the next one."]

actually, I think the former is ultimately clearer..


AFAIR the reason c++ introduced references was to allow operator overloading.

The differences are as follows (in c++ only, as java reference are like c++ pointers as someone said) -

reference: must be initialized to something; pointer: may be left uninitialized

reference: address of reference can not be taken (note it may not actually exist, the compiler isn't just hiding it) pointer: address of the pointer can be taken and is different to the address of the thing it points to

reference: can not be re-seated to refer to something other than what it was initialized with pointer: can be re pointed at anything

a pointer is, well, a pointer to something. a reference is an alias which just happens to be implemented as a pointer by the compiler in some situations. i.e. they are definitely not the same thing for c++.

-- JamesKeogh

reference: cannot be used to perform "pointer arithmetic". pointer: can be used for "pointer arithmetic".

reference: can extend the lifetime of temporaries. pointer: cannot extend the lifetime of temporaries.


See also: PointersVersusKeys WhatIsaPointer


CategoryComparisons CategoryPointer CategoryReferences


EditText of this page (last edited November 8, 2014) or FindPage with title or text search