`&` in function parameter list

71 views Asked by At

I saw this in some code and I'm confused about one thing:

struct mystrct {...};
typedef mystrct* ptr_mystrct;

void fun1(ptr_mystrct &val)
{...}
void fun2(ptr_mystrct val)
{...}

main()
{
  mystrct foo;
  ptr_mystrct ptr_foo = &foo;
  fun1(ptr_foo);
  fun2(&foo); //this works fine
  fun1(&foo); //this is NOT valid (compiler error)
}

What is the purpose of & before val? At first I thought it will take the address to the pointer (val will point to ptr_foo location) but it apparently doesn't.

Also, why does fun2(&foo) compile where fun1(&foo) doesn't?

2

There are 2 answers

2
user3344003 On BEST ANSWER

It declares the parameter as a reference. The parameter becomes in/out rather than C++/C's normal in only.

This updates the structure passed to the function.

 void fun1 (ptr_mystruct &val)
 {
    val = somevalue ;
 }

This updates a copy of the parameter in fun2 so the caller never sees the change.

 void fun2 (ptr_mystruct val)
 {
    val = somevalue ;
 }

Here fun2 expects a pointer a pointer to a structure. Works

fun2(&foo); //this works fine

Here fun1 expects a pointer to a structure and you are passing a pointer to a pointer:

fun1(&foo); //this is NOT valid (compiler error)

IMHO, this example has one level of indirection more than needed for fun1. This is what you really need for a structure passed by reference:

void fun1(mystrct &val)

This is what you'd do in the olde days of C before references to make a structure read/write

void fun2(ptr_mystrct val)
0
Barry On

Dropping the typedefs, we have:

void fun1(mystrct*& val);

fun1(&foo);

fun1 takes an lvalue reference to a pointer to mystrct. &foo is indeed a pointer to mystrct, but it's an rvalue (specifically a prvalue), not an lvalue, so the types mismatch. You can think of it as &foo is a temporary value, and you can't take an non-const lvalue reference to a temporary.

This is the equivalent error to trying to do something like:

void fun(int& );
fun(1);

fun2 just takes a pointer - not a reference - so fun2(&foo) is totally fine.