views:

447

answers:

10

This is a question from an exam in an advanced course in OOP, taught in C++ (in TAU university, this semester):

Q: What is the difference between a C++ pointer and a reference?

A.  A reference is the entire object while a pointer is only the address of it.
B.  The same meaning, and difference is only in syntax and usage.
C.  The syntax used to access the object.
D.  Pointers are simple address to the object while a reference uses the virtual table.

Which is the correct answer?

The course teacher claims that A is the correct one, and that a reference to an object is, in fact, the object itself. Is that correct? I realize that accessing the reference is equivalent to accessing the object itself, however, when destructing a reference, we do not destruct the object itself. A reference is an alternative name for the object, but saying that reference==object true?

BTW, the lecturer gave the following link to an faq as support for his claim, a quote:

"Important note: 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 still, I believe this is incorrect.

+5  A: 

There's a distinction between a reference and an object - you can have multiple references to the same object. An object has 'identity', while a reference itself doesn't really.

While the mechanics of a reference are quite different than those of a pointer, I'd say that conceptually, a reference is actually quite similar to a pointer.

Michael Burr
Ben Voigt
+24  A: 

They're all wrong.

A reference is essentially a synonym for another object. Internally, it is often implemented as a pointer, but it has the syntax as if it were the object it refers to.

A pointer is a separate object that stores the memory address of the object it points to (or 0 if it doesn't point to an object).

You could say that the reference is the object that it refers to (it certainly acts that way), but it is not. If a reference goes out of scope then the object it refers to is not destructed, so the reference is not the object.

Peter Alexander
Also, the reference's static type is not the same as the object's static type.
Ben Voigt
+1 for a clear and concise definition of an often misunderstood (even by professors, it seems!) principle.
Abel
They become the same thing when you go a bit deeper. :D http://stackoverflow.com/questions/1640355/whats-the-low-level-difference-between-a-pointer-an-a-reference
CrazyJugglerDrummer
+4  A: 

(B) is the closest, but still not exactly correct. A reference is syntactic sugar for a const pointer. Just like a const pointer, it must be bound to an lvalue at initialization, and can never be rebound. Just like a const pointer, it is polymorphic.

EDIT: Short proof that (A) is incorrect, since at least a couple people are defending it:

struct A { int x; int f() { return 1; } }
struct B : public A { int y; int f() { return 2; } }

B b;
A& a = b;

assert(sizeof(a) == sizeof(b)); // fail
assert(a.f() == b.f()); // fail again
Ben Voigt
But unlike a const pointer it cannot be bound to NULL.
EFraim
const-references may be bound to r-values. `const int` is valid. The const-pointer equivalent is not.
Peter Alexander
@Ben Voigt: sometimes (many times) a compiler must use pointers to implement reference semantics. However, you're over-generalizing. The *meaning* of references (their semantics) means that the compiler can treat them completely differently than pointers. This answer relies far too heavily on a subset of implementation details.
Cogwheel - Matthew Orlando
@EFraim: Well, they can if you really want to shoot yourself in the foot: int
SigTerm
@SigTerm: Is this really defined behavior? (I mean without referencing a, of course)
EFraim
Introduction of a nameless local variable is still syntactic sugar. And while it's illegal to bind a reference to NULL, it's not impossible, and a const pointer to NULL is equally useless.
Ben Voigt
@EFraim No, it isn't.
anon
@Ben: const pointer to NULL is *not* useless. Think of conditional initialization, depending on some condition.
EFraim
Ben Voigt
SigTerm
In cases of dynamic polymorphism where references are being passed around various functions, they are indeed treated like pointers. However, that's not the only time we use references in the language. Some template techniques rely heavily on the fact that references can be collapsed into nothing during compilation. There are a few other uses where the compiler can perform optimizations that would be otherwise impossible with pointers.
Cogwheel - Matthew Orlando
@Sig It is undefined because dereferencing a null pointer is always undefined behaviour.
anon
@EFraim: Anything you can do with a const pointer to NULL, I can do with a reference. A const pointer to NULL has the following characteristics: It compares equal to other const pointers to NULL of the same type, different from all non-NULL pointers, and all other usage is undefined. `template <typename T> T return *static_cast<T*>(t); }` Let's see... identity comparison to other null_reference values of the same type and different from all other values... check. All other operations are undefined behavior... check.
Ben Voigt
@Ben Voigt: "I don't know of any way in which a compiler can treat a reference differently from a const pointer." If you're talking about function parameters, then references are *probably* pointers. However, inside functions (i.e. for references that are not function parameters) compiler could easily simply access original variable instead each time you manipulate reference. I.e. it could easily store int in a register and access that register when you manipulate reference to that int. I.e. pointer must store address. Reference doesn't have to do it.
SigTerm
@Cogwheel: If you don't take an address of a non-volatile pointer (or any other non-volatile variable), it too can be optimized away. In fact, the unnamed locals introduced by references make optimization harder for references than for const pointers.
Ben Voigt
@SigTerm: Citation please. I'm unfamiliar with any clause in the standard that prohibits optimizing away pointer access in exactly the same way as references.
Ben Voigt
@Ben Voigt: I will not search for appropriate citation, because the discussion subject is not interesting enough for me. As far as I know, const pointer is guaranteed to be address. Reference is not. That's enough for me.
SigTerm
Ben Voigt
@Ben Voigt: Citation from C++ standard, please.
SigTerm
I quote footnote (4) of section 1.9 [intro.execution]: "Under the “as-if” rule an implementation is allowed to store two objects at the same machine address or not store an object at all if the program cannot observe the difference (1.9)."
Ben Voigt
That's the wording in the C++0x final committee draft, which is publicly available, but the *as-if* rule is present in C++03 as well.
Ben Voigt
A: 

All answers are incorrect, A is closest.

Pointer is address of object which is object itself.
"Object" is "something" somewhere in a memory. Class instance, int, float, etc.
Reference is an alternative way of accessing an object. It is reference to an object, but not the object itself. It may or may not be implemented as pointer. You may think about it as an alternative object name, but this isn't exactly right. The closest correct descriptions I can think of is "alternative interface for accessing/manipulating object"(unfortunately "interface" sounds misleading if you take OOP in account, although it is (IMO) most correct one).

SigTerm
+3  A: 

Just to climb on my hobby-horse for a moment, Universities have no business in teaching people how to program in specific computer languages. The fact that they do is simply an indicator of how degraded they have become over the past 30 years. I worked for the University of London from 1979 to 1983 as a microbiology technician and programmer, and the microbiology students (note not CS students!) were expected to pick up how to use the computers and to program more or less on their own, which they did, as much as they needed to.

But nowadays even CS students seem to be spoonfed everything, and tested on that "knowledge" by almost impossible to fail tests like the one quoted by the OP.

Gah!!!

anon
couldn't agree more. However, the above course is one of the most popular among choice courses in CS degree in TAU.
amitlicht
However things like references and pointers are fundamentals and should be taught (IMHO) by example of *some* programming language.
EFraim
@EFraim Yes, but the longer I live the more I understand why Knuth used an assembly language in his books, and an artificial one at that.
anon
@Neil, You seem to be saying that students should be taught the general and use their own curiosity and ambition to apply those skills to the specific. It's equally valid and useful to teach students a wide variety of specific implementations and allow their curiosity and intelligence to lead them to recognizing and discerning the general principles of Computer Science.What's not acceptable is to teach them a few specifics and then call it a day. That's vocational training, not a CS education.
Jesse Dhillon
A: 

The question isn't about objects and references, it's about pointers and references. The point is that pointers denote a memory location and references denote an object- a higher level semantic construct. Simple as that.

And the teacher already gave you the answer anyhow: A -> correct answer.

Good luck in your studies.

Holland Whitten
The fact that the instructor said that something is true does not necessarily make it true...
amitlicht
In the context of a class, I disagree. In a grade oriented value system the giver of grades is the ultimate arbiter of truth. That's what makes 'a' right, not my or your opinion of it.
Holland Whitten
The giver of grades is the ultimate arbiter of whether the diplomas are worth the paper they're printed on. IMHO that's slightly different from "truth".
Ben Voigt
Go to school with that attitude and you'll come away with something even less valuable. At any rate I choose not to argue with idiots because from a distance it's hard to tell who is who. Sayonara.
Holland Whitten
If it is difficult from a distance to know who is "who", how do you know with whom you are choosing not to argue? Specifically, why do you say these people may be "idiots"? I gave you a -1 for casting the word "idiot" at Ben, but as long as we are being frank, I was very disappointed in you for your sychophancic following of some random "University instructor."
Heath Hunnicutt
@Holland: If you are there to get a diploma and get out, then what the instructor says is right. If you are there to learn something, then what the instructor says may well be wrong, and you have the more difficult task of learning both what will pass the test and what's actually correct. And, personally, I do argue with idiots sometimes.
David Thornley
A: 

I believe your teacher is confusing a metaphor and a concrete statement. A reference definitely is not the actual object, and it is implemented as a "funny looking pointer" but the point of that statement is that you are to think of a reference as the actual object being referenced, you are not to think or program as if you are handling a pointer. Syntactically, accessing a reference to an object is identical to accessing the object itself, except in a few cases mentioned in the comments below.

Jesse Dhillon
Except when it isn't. See the edit to my answer.
Ben Voigt
Why did you mod me down? I said that objects and references behave identically. If we take your example code and remove the references, so it becomes A a = b; instead of A you get the same result! All you're doing is a cast from a derived type to a base type, which you can do with a reference or an object.
Jesse Dhillon
First you said that accessing a reference is identical to accessing its referent. When I disproved that, you argue that a reference is the same as a copy (slice) of an object? I assure you that neither is the case. Would you like an example showing how `A` behaves differently from `A a = b;`?
Ben Voigt
Yeah I actually would like to see that.
Jesse Dhillon
@Jesse Dhillon: How about this: http://ideone.com/clWw2
jpalecek
"I said that objects and references behave identically" they don't if you want to denote their identity. You cannot pass references as template non-type arguments, for example. But you can do so with objects, provided their name has external linkage.
Johannes Schaub - litb
I've amended my answer to allow for the exceptions that you guys have mentioned. I think, however, that the cases mentioned here are extreme corner cases, bordering on contrived. Nonetheless, they do prove that what I said was incorrect.
Jesse Dhillon
+3  A: 

An important thing is to differentiate between:

  • Reference as an expression
  • Reference itself

The FAQ and the teacher seem to talk about the first point, but the teacher's question is formulated as if it were asking about the second point. To explain the point of view of the FAQ, consider what the Standard describes as the very first stage of expression processing

If an expression initially has the type "reference to T" (8.3.2, 8.5.3), the type is adjusted to "T" prior to any further analysis, the expression designates the object or function denoted by the reference, and the expression is an lvalue

After this transformation, a reference and the object or function it designates cannot be distinguished anymore using that expression. But that doesn't make a reference equivalent to an object. The former just refers to the latter. Even less so since references can also refer to functions.

Now, a reference itself is just that - an entity that happens to refer to an object or function but that doesn't store something on its own.

The same mistake in arguing is sometimes made by people when they say that arrays in C would be just pointers. What they really mean is that arrays in expressions are (mostly) just pointers. But that doesn't make both of them equal in their own right.

Johannes Schaub - litb
+1  A: 

Answering to whether the teacher is wrong: Simple logic. Strictly speaking, it is what the name (and the standard) say: It is a reference to (="a name of") the object, NOT the object itself. As said before, when the reference variable runs out of scope, the object's destructor is not called, therefore the reference is not the object.

#include <iostream>
class A {
public:
    ~A()
    {
            std::cout << "~A() called.\n";
    }
};
void f(A &a)
{
    // a running out of scope...
}
int main()
{
    A a;
    std::cout << "calling f()\n";
    f(a);
    std::cout << "done calling f()\n";
    return 0;
}
Robert Drehmel
+1  A: 

One of the big differences between pointers and references that I haven't seen mentioned is that a pointer can be NULL while a reference can't. That doesn't mean the object a reference pointers to can't go out of scope resulting in the same types of issues people have with pointers, merely that there is no "no assigned" state.

wheaties