0

I was hoping someone could explain to me why a function with a reference parameter would be called rather than one with a pointer parameter, given something like the following:

int Func1 ( int & a );
int Func1 ( int * a );

int main()
{
   int y = 1;
   int & x = y;
   int * z = & y;

   Func1(y); // Calls reference version
   Func1(&y); // Calls pointer version
   Func1(z); // Calls pointer version

   return 0;
}

int Func1 ( int & a )
{
    cout << "Reference param Func1 called" << endl;
    a = a + 1;

    return a + 1;
}

int Func1 ( int * a )
{
    cout << "Pointer param Func1 called" << endl;
    *a = *a + 1;

    return *a + 1;
}

I'm confused as to how the decision is made to call the pointer parameter version of Func1 for the Func1(&y) call rather than the reference parameter version of Func1. Also, why is the reference parameter version of Func1 not chosen for the Func1(z) call? If z holds an address, I don't see why the address can't be passed into the reference parameter for Func1( &a ).

Victor Brunell
  • 5,668
  • 10
  • 30
  • 46
  • Its about the type, the type of z is a pointer. – Barış Uşaklı Dec 09 '13 at 18:24
  • Ah, I see. So Func1( int & a ) creates a reference, it doesn't receive an address as a passed argument, whereas Func1( int * a ) receives an address as a passed argument, which can be of the form &y or z, where z is a pointer? – Victor Brunell Dec 09 '13 at 18:36
  • @Caulibrot: `&y` *is* a pointer. So it's an example of "z, where z is a pointer". – Steve Jessop Dec 09 '13 at 18:45
  • If &y is a pointer, is its scope as a pointer simply the time from when it's passed to when it's received? I know that y has local scope in main, but I'm not sure about when &y as a pointer is created and destroyed. – Victor Brunell Dec 09 '13 at 18:50
  • 1
    @Caulibrot: `&y` is an rvalue of scalar type, meaning that it's a value without (as far as the standard is concerned) any particular location in memory. In this respect it's the same as the value that results from, say, `y+1`. It doesn't have a scope (because names have scope, objects and values don't). It doesn't really have a lifetime either, objects have lifetime. It's just the value used to initialize the variable `a` inside `int Func1(int *a)`. The scope and duration of `a`, then, are both "until the call returns". – Steve Jessop Dec 09 '13 at 18:52
  • Got it. I think I was confused about the semantic difference between lifetime and scope. Lifetime applies to objects, whereas scope applies to named variables, is that correct? – Victor Brunell Dec 09 '13 at 18:55
  • @Caulibrot: More or less. Specifically scope applies to the name, and it means "the part of the source file in which the name means that variable". A variable is defined in the standard to mean a named object. The lifetime of an object (whether it's named or not) is the period during the runtime of the program in which the object "exists". In the case of builtin types "exists" basically means there's some memory currently used for the purpose of containing that object. For types with constructors "exists" means constructed but not yet destroyed. – Steve Jessop Dec 09 '13 at 19:01

1 Answers1

1

int Func1 ( int & a ); matches calls where the argument expression has type int (and is eligible to have a non-const reference taken to it). int Func1 ( int * a ); matches calls where the argument expression has type int*.

If z holds an address, I don't see why the address can't be passed into the reference parameter for Func1( &a ).

Well, you could achieve that by calling Func1(*z).

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699