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
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;
}
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 typeT
(that is, they are not base class subobjects).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With