Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a c++ reference considered safer than a pointer?

When the c++ compiler generates very similar assembler code for a reference and pointer, why is using references preferred (and considered safer) compared to pointers?

I did see

  • Difference between pointer variable and reference variable in C++ which discusses the differences between them.

EDIT-1:

I was looking at the assembler code generated by g++ for this small program:

int main(int argc, char* argv[])
{
  int a;
  int &ra = a;
  int *pa = &a;
}
like image 804
yasouser Avatar asked Jan 17 '11 17:01

yasouser


2 Answers

It's considered safer because a lot of people have "heard" that it's safer and then told others, who now have also "heard" that it's safer.

Not a single person who understands references will tell you that they're any safer than pointers, they have the same flaws and potential to become invalid.

e.g.

#include <vector>

int main(void)
{
    std::vector<int> v;
    v.resize(1);

    int& r = v[0];
    r = 5; // ok, reference is valid

    v.resize(1000);
    r = 6; // BOOM!;

    return 0;
}

EDIT: Since there seems to be some confusion about whether a reference is an alias for an object or bound to a memory location, here's the paragraph from the standard (draft 3225, section [basic.life]) which clearly states that a reference binds to storage and can outlive the object which existed when the reference was created:

If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:

  • the storage for the new object exactly overlays the storage location which the original object occupied, and
  • the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and
  • the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
  • the original object was a most derived object of type T and the new object is a most derived object of type T (that is, they are not base class subobjects).
like image 80
Ben Voigt Avatar answered Oct 12 '22 22:10

Ben Voigt


It depends how you define "safer".

The compiler won't let you create an uninitialised reference, or one that points to NULLness, and it won't let you accidentally make your reference refer someplace else whilst you're using it. These stricter rules also mean that your compiler can give you some more warnings about common mistakes, whereas with pointers it's never really sure whether you meant to do what you did, or not.

On the other hand, the transparency of the syntax -- namely, what Alexandre C. mentioned about what it looks like at the call-site to pass an argument as a reference -- makes it quite easy not to realise that you're passing a reference. Consequently, you might not realise that you're supposed to maintain ownership and lifetime of the argument, or that your argument may get permanently modified.

like image 26
Lightness Races in Orbit Avatar answered Oct 12 '22 23:10

Lightness Races in Orbit