Categories
c++ c++-faq pointers reference

What are the differences between a pointer variable and a reference variable?

3731

What is the difference between a pointer variable and a reference variable?

25

  • 132

    I think point 2 should be “A pointer is allowed to be NULL but a reference is not. Only malformed code can create a NULL reference and its behavior is undefined.”

    Oct 8, 2010 at 17:21

  • 28

    Pointers are just another type of object, and like any object in C++, they can be a variable. References on the other hand are never objects, only variables.

    – Kerrek SB

    Jun 16, 2012 at 10:14

  • 29

    This compiles without warnings: int &x = *(int*)0; on gcc. Reference can indeed point to NULL.

    – Calmarius

    Aug 13, 2012 at 9:00

  • 28

    reference is a variable alias

    – Khaled.K

    Dec 23, 2013 at 8:53

  • 26

    I like how the very first sentence is a total fallacy. References have their own semantics.

    Jun 1, 2014 at 1:58


495

What’s a C++ reference (for C programmers)

A reference can be thought of as a constant pointer (not to be confused with a pointer to a constant value!) with automatic indirection, ie the compiler will apply the * operator for you.

All references must be initialized with a non-null value or compilation will fail. It’s neither possible to get the address of a reference – the address operator will return the address of the referenced value instead – nor is it possible to do arithmetics on references.

C programmers might dislike C++ references as it will no longer be obvious when indirection happens or if an argument gets passed by value or by pointer without looking at function signatures.

C++ programmers might dislike using pointers as they are considered unsafe – although references aren’t really any safer than constant pointers except in the most trivial cases – lack the convenience of automatic indirection and carry a different semantic connotation.

Consider the following statement from the C++ FAQ:

Even though a reference is often implemented using an address in the
underlying assembly language, please do not think of a reference as a
funny looking pointer to an object. A reference is the object. It is
not a pointer to the object, nor a copy of the object. It is the
object.

But if a reference really were the object, how could there be dangling references? In unmanaged languages, it’s impossible for references to be any ‘safer’ than pointers – there generally just isn’t a way to reliably alias values across scope boundaries!

Why I consider C++ references useful

Coming from a C background, C++ references may look like a somewhat silly concept, but one should still use them instead of pointers where possible: Automatic indirection is convenient, and references become especially useful when dealing with RAII – but not because of any perceived safety advantage, but rather because they make writing idiomatic code less awkward.

RAII is one of the central concepts of C++, but it interacts non-trivially with copying semantics. Passing objects by reference avoids these issues as no copying is involved. If references were not present in the language, you’d have to use pointers instead, which are more cumbersome to use, thus violating the language design principle that the best-practice solution should be easier than the alternatives.

17

  • 22

    @kriss: No, you can also get a dangling reference by returning an automatic variable by reference.

    – Ben Voigt

    Nov 2, 2010 at 6:14

  • 19

    @kriss: It’s virtually impossible for a compiler to detect in the general case. Consider a member function that returns a reference to a class member variable: that’s safe and should not be forbidden by the compiler. Then a caller that has an automatic instance of that class, calls that member function, and returns the reference. Presto: dangling reference. And yes, it’s going to cause trouble, @kriss: that’s my point. Many people claim that an advantage of references over pointers is that references are always valid, but it just isn’t so.

    – Ben Voigt

    Nov 2, 2010 at 13:15

  • 6

    @kriss: No, a reference into an object of automatic storage duration is very different from a temporary object. Anyway, I was just providing a counter-example to your statement that you can only get an invalid reference by dereferencing an invalid pointer. Christoph is correct — references are not any safer than pointers, a program which uses references exclusively can still break type safety.

    – Ben Voigt

    Nov 2, 2010 at 15:15

  • 9

    References are not a kind of pointer. They are a new name for an existing object.

    – catphive

    Jul 20, 2011 at 1:28

  • 27

    @catphive: true if you go by language semantics, not true if you actually look at the implementation; C++ is a far more ‘magical’ language that C, and if you remove the magic from references, you end up with a pointer

    – Christoph

    Jul 23, 2011 at 9:07

222

If you want to be really pedantic, there is one thing you can do with a reference that you can’t do with a pointer: extend the lifetime of a temporary object. In C++ if you bind a const reference to a temporary object, the lifetime of that object becomes the lifetime of the reference.

std::string s1 = "123";
std::string s2 = "456";

std::string s3_copy = s1 + s2;
const std::string& s3_reference = s1 + s2;

In this example s3_copy copies the temporary object that is a result of the concatenation. Whereas s3_reference in essence becomes the temporary object. It’s really a reference to a temporary object that now has the same lifetime as the reference.

If you try this without the const it should fail to compile. You cannot bind a non-const reference to a temporary object, nor can you take its address for that matter.

9

  • 7

    but whats the use case for this ?

    Oct 22, 2009 at 14:10

  • 24

    Well, s3_copy will create a temporary and then copy construct it into s3_copy whereas s3_reference directly uses the temporary. Then to be really pedantic you need to look at the Return Value Optimization whereby the compiler is allowed to elide the copy construction in the first case.

    Oct 22, 2009 at 18:14

  • 7

    @digitalSurgeon: The magic there is quite powerful. The object lifetime is extended by the fact of the const & binding, and only when the reference goes out of scope the destructor of the actual referenced type (as compared to the reference type, that could be a base) is called. Since it is a reference, no slicing will take place in between.

    Jan 14, 2010 at 17:06

  • 11

    Update for C++11: last sentence should read “You cannot bind a non-const lvalue reference to a temporary” because you can bind a non-const rvalue reference to a temporary, and it has the same lifetime-extending behaviour.

    – Oktalist

    Nov 10, 2013 at 20:14

  • 8

    @AhmadMushtaq: The key use of this is derived classes. If there is no inheritance involved, you might as well use value semantics, which will be cheap or free due to RVO/move construction. But if you have Animal x = fast ? getHare() : getTortoise() then x will face the classic slicing problem, while Animal& x = ... will work correctly.

    Nov 2, 2017 at 11:04