4

What is the difference between the following two parameter types? The first accepts a pointer, which is in effect a memory address, and the second is also a memory address?

foo(float& bar)
{
    // do stuff
}

foo(float* bar)
{
    // do stuff
}

Could you not call both with:

float pow = 3.0f;

foo(&pow);

or

float* pow = 3.0f;

foo(pow);
Dollarslice
  • 9,917
  • 22
  • 59
  • 87
  • 2
    Wait... since when if `float* pow = 3.0f` valid? – wormsparty Oct 06 '11 at 15:59
  • possible duplicate of [difference between a pointer and reference parameter?](http://stackoverflow.com/questions/620604/difference-between-a-pointer-and-reference-parameter) – David Nehme Oct 06 '11 at 16:10

5 Answers5

12
  • A pointer can be NULL, while a reference can't. This can be useful if you need to pass a NULL object for whatever reason.

  • With the pointer syntax, you pass a pointer when you call the function. With references, you just pass the variable:

    refer(float& bar) {}
    point(float* bar) {}
    
    float afloat = 1.0f;
    
    refer(afloat);
    point(&afloat);
    

    This means with the pointer syntax you have to pass a pointer when you call the function. With the reference syntax, you don't know if the function takes it by reference or by value without looking at the function definition.

  • With the reference syntax you don't have to dereference the pointer in your function, and work with it more naturally in your // do stuff section.

    foo(float& bar)
    {
        bar = 3.0f;
    } 
    
    // versus
    
    foo(float* bar)
    {
        *bar = 3.0f;
    }
    
Aillyn
  • 23,354
  • 24
  • 59
  • 84
  • 1
    You can also change what the pointer points to, but you can't change what a reference references. – Rob K Oct 06 '11 at 16:35
  • I was under the impression that the call for the first function would still have to be foo(&variable); but from some of the other answers I see it should really be foo(variable); So with a function parameter that is a memory address - you just pass the actual variable and the program converts it on the way? – Dollarslice Oct 06 '11 at 16:39
2

No, they are not the same. The first is taking a parameter by reference and would be called like this:

float pow = 3.0f;
foo(pow) // foo can change the value of pow!

the second accepts a pointer and could be called by either of your examples (both of which are passing a pointer, not a reference).

NOTE: your second example, while it passes a float* does not properly initialize the pow variale, and therefore won't compile. Instead, something like this would work:

float *pow = new float(3.0);
foo(pow);
delete pow;

While references have similarities to pointers, it is not mandated that they are implemented internally by pointers. For example, often the compiler can inline calls and just modify the argument directly, no pointer passed in that case.

In general, think of a reference as "just another name" for a variable. For example:

Person Samuel_Clemens;
Person &Mark_Twain(Samuel_Clemens); // just another name
Evan Teran
  • 87,561
  • 32
  • 179
  • 238
1

The difference is that the first cannot receive a null pointer, while the second can. But with a bit of effort you can make the first receive null pointer too:

float *a = null;
pow(*a);

Edit: All the following proved to be wrong, I'll keep it as reference for the comments:

The difference is that the reference version will throw an exception when dereferencing a null reference while pointer version will just segfault:

float *a = null;
float &b = *a; // works... somehow?

b = 1; // throws exception
*a = 1; // segmentation fault

Daniel
  • 30,896
  • 18
  • 85
  • 139
  • 1
    A NULL reference cannot exist in an valid c++ program, Once your reference is null by any means the program is an Undefined Behavior anyways. – Alok Save Oct 06 '11 at 15:49
  • This is abuse of dereference operator, TBH. – Griwes Oct 06 '11 at 15:49
  • 2
    -1: *the reference version will throw an exception*. No, both versions will have undefined behavior. – Robᵩ Oct 06 '11 at 15:50
  • would I be right in saying that, and this is perhaps oversimplified, but you use a reference when you simply want a memory address, but beyond that you don't need to hold on to the value. and a pointer is used more when you want an object to hold on to that value so you can use it in a more persistent way. ...? – Dollarslice Oct 06 '11 at 15:51
  • Can you Explain how did you get this fancy idea of NULL references throwing Exceptions? Any references(ofcourse I mean doccumentation) links? BTW, I havent downvoted yet in the beleif that you have been misled by some faulty doccumentation. – Alok Save Oct 06 '11 at 15:52
  • @Als: on my mingw g++ it throws an exception (have no clue why). but on mac g++ it does segmentation fault. – Daniel Oct 06 '11 at 15:54
  • 1
    @Dani: Now you know, what **Undefined Behavior(UB)** means, It means that anything can happen, the standard does not enforce the compilers to guarantee any specific behavior when UB occurs. Your program may crash or not, but there is no guarantee of any behavior. – Alok Save Oct 06 '11 at 15:57
0

float* is a pointer to a float number, whereas float& is a reference to a float number.

With a pointer, you can say function(null) letting the argument point to null (which represents nothing in particular, and often causes undefined behaviour (=crash)). A reference can't reference to nothing (at least not that easy).

When using float*, you will always treat this argument as a pointer, and the compiler does as well. When you use float&, you can treat it as a "normal" (i.e. non-pointer) variable, but it is as if you were using a pointer.

phimuemue
  • 34,669
  • 9
  • 84
  • 115
0

In the first (reference), you are interested on reading and writing the original variable. In the secondth (pointer), you are interested on receiving the address of the original variable.

The difference is mostly taste, except the fact that the pointer version allows you to not-pass any value using a NULL value.

vz0
  • 32,345
  • 7
  • 44
  • 77