7

Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?

For example, I have two functions that do the same thing:

int func(int &a)
{
   return a+1;
}

and

int func2(int *a)
{
   return *a+1;
}

What is the advantage of using func over func2 when calling any one of these functions?

Community
  • 1
  • 1
Kang Min Yoo
  • 805
  • 1
  • 9
  • 20
  • The only advantage, in my opinion, is the ability to take a NULL argument. There are already some good questions here on this topic. – chris Apr 28 '12 at 01:57
  • 3
    See http://stackoverflow.com/questions/57483/what-are-the-differences-between-pointer-variable-and-reference-variable-in-c – jedwards Apr 28 '12 at 02:00
  • I was asking this because a friend in our group project insisted us to use references rather than pointers by claiming that references are 'superior' than the pointers. I guess I'll just stick with pointers then since I got more used to it after doing some C projects. – Kang Min Yoo Apr 28 '12 at 02:03
  • 3
    @user803253: Yes, they are superior whenever you can use them -- they admit fewer mistakes than pointers. – Billy ONeal Apr 28 '12 at 02:05
  • @BillyONeal but not if you can manage the pointers well? – Kang Min Yoo Apr 28 '12 at 02:08
  • 1
    @user803253: It's not an issue of being able to manage pointers well. It's an issue of preventing "stupid" mistakes that everyone makes. For instance, [passing null pointers to functions that require pointers to data](http://stackoverflow.com/questions/4390007/in-either-c-or-c-should-i-check-pointer-parameters-for-null). If the compiler can catch mistakes for you, why not take advantage of that fact? – Billy ONeal Apr 28 '12 at 20:43

4 Answers4

12
  • A reference cannot be assigned null directly, but a pointer can be.
  • A reference cannot be reassigned to point to something else, but a pointer can be.

Both these can be advantages or disadvantages, depending on the situation.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
  • Reference can, in fact, be a null. But is a lot harder to pull off than it is with pointers. In fact, references is just a syntactical sugar. –  Apr 28 '12 at 01:59
  • @VladLazarenko, true, but it kind of defeats the purpose of using them. You end up with some pretty bad code. – chris Apr 28 '12 at 02:00
  • 3
    @VladLazarenko If I am not mistaken, constructing a `null` reference is undefined behavior. – Sergey Kalinichenko Apr 28 '12 at 02:02
  • 2
    @VladLazarenko only in a malformed program can references be `NULL`, so it's basically correct to say they can't be `NULL`. – Seth Carnegie Apr 28 '12 at 02:04
  • A reference is not merely syntactic sugar. A struct/class can contain a reference, and so that reference is actually a real run-time value made out of bits. – Kaz Apr 28 '12 at 02:04
  • 2
    @Kaz he means it's syntactic sugar for a pointer. – Seth Carnegie Apr 28 '12 at 02:04
  • @SethCarnegie, unfortunately it's all too easy to create a NULL reference by accident. Malformed programs are created every day. – Mark Ransom Apr 28 '12 at 02:08
  • Guys, what I mean is that reference is not mapped into any "physical" entity, and exists only on a language level. Pointers, on the other hand, exist in lower levels. I.e. they are loaded into registers of the CPU and are used to read/write memory. It is a syntactic sugar as much as templates, for example. It is important to understand why they are there and how they are being treated by compiler to generate lower level code. It also shows intent of the author of the function etc, but it is "synthesized" either into a pointer, or a copy of the POD, or is eliminated completely. Huh. –  Apr 28 '12 at 02:10
  • 1
    @MarkRansom yes, but it's pointless to include undefined behaviour in malformed programs into our definitions of what can and can't be done. So a reference can't be `NULL` because the standard says so, and any other behaviour falls outside the scope of the universe. Don't you think so? – Seth Carnegie Apr 28 '12 at 02:13
  • 2
    @SethCarnegie, my attitude is colored by a multi-day debugging session caused by a reference that turned out to be NULL. And it wasn't even my code! – Mark Ransom Apr 28 '12 at 02:15
  • A reference is mapped to a physical entity (has a physical realization) and is loaded into CPU registers, etc. Only references within a lexical scope of code can be treated as compile-time aliases, especially if they are just references to local variables in that same scope. What if I make a reference like this: `int &x = a->b.c[i][j].foo;`. The compiler is not gonna replace every occurence of `x` with that original expression. Moreover, `a`, `i` and `j` could change! Nope; there has to be a little pointer stashed somewhere, representing the address of the `int` that is now denoted by `x`. – Kaz Apr 28 '12 at 03:07
  • If a reference goes bad (NULL, or invalid), the root cause is going to be a pointer. – Kaz Apr 28 '12 at 03:08
2

Both of your functions are wrong. Since they don't modify the argument passed in, they should take them in as const, like this:

int func(const int &a)
{
    return a+1;
}

int func2(const int *a)
{
    return *a+1;
}

Now here's an advantage for references, I can pass rvalues into the reference version:

func(10);
func(func(func(10)));

I can't do that with the pointer version.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • Is the const part necessary? I thought it was there just for safety? – Kang Min Yoo Apr 28 '12 at 02:27
  • 2
    @user803253: It's necessary if you consider good design necessary, and I do. No it's not just for safety. It also allows you to pass actual const objects into the function. Why shouldn't the user be able to pass const objects into a function that doesn't modify the passed object? Not allowing the user to do that is, like I said, bad design. – Benjamin Lindley Apr 28 '12 at 02:29
  • 2
    I wouldn't say wrong. I'd say they could be improved. – Alexey Frunze Apr 28 '12 at 03:24
  • 1
    @Alex: I would say wrong. When an improvement requires so little effort and has no perceivable drawbacks, to not make it is wrong. – Benjamin Lindley Apr 28 '12 at 03:45
1

The pointer is more flexible, it can also be predefined in the declaration like:

 int func2(int *a = nullptr);

Which does not work in your simple case but in many others it does.

The pointer may also more easily be used for other things, like storing in a list, typacasting it and other things.

And yes, the reference cannot be reassigned.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
HardCoder
  • 3,026
  • 6
  • 32
  • 52
1

If a is an object that overloads standard C++ operators (e.g. operator[] or operator*), clients can use it in more standard C++ syntax like a[i], instead of a->operator[](i) or (*a)[i]

franji1
  • 3,088
  • 2
  • 23
  • 43