0

consider the below code

int& func1() {
    int x = 2;
    return x;
}

int& func2(int &x) {
    return x;
}

int main() {
    int x = func1();
    cout<<"\n : "<<x;
    int y = 3;
    x = func2(y);

    cout<<"\n : "<<x<<"\n";
}

output:

 : 2
 : 3

The code is working absolutely fine , but I have few doubts that I have listed below:

  1. In func1() I have returned a non_reference variable "x" but the return type is reference to an int, so how is the conversion happening and what part of "x" function is actually returning.

  2. In func1() "x" is returned as reference but being a stack variable how the reference of x can be returned , I mean it will have no significance after the completion ( I am relating this point to the logic " Functions should not return the pointers whose memory is allocated in statically").

  3. In func1() it is returning a non refrence variable "x" as refrence to an int and in func2() it is returning a refernce variable "x" as refrence to an int. As both "x" are of different type but why return type is same..

I am confused because I am trying t relate C++ with c as in that everything is clear but here majorily due to lack of memory layout description of refrence variable, so if some could tell about that also then it will be very helpful to me

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Learner
  • 59
  • 8

2 Answers2

3

In func1, what you are returning is a reference to something. This something is x, which is local to func1, whose lifetime ends upon returning. Then, in main, you assign the contents of the referred-to variable (x of func1, which is eating dandelions by the roots) to initialize main's local variable x. This is undefined behaviour, which means that the program is allowed to interpret this as anything it wants, formatting your hard drive or anything. (most probably, func1 returned the pointer to the variable of the called stack frame, which probably still contains the right value, because why bother erasing the values on the stack when they will be crushed by the next function call anyway?) Anyway, would the program be compiled with other optimization options, it may give another answer.

In func2, what you are returning is a reference to something. This something is what is referred-to by x, which refers to main's y. Then, you assign to main's x the value of the referred-to variable, which is y.

With regards to your question of the memory layout of references, in C, pointers are addresses in memory. Period. No escape. In C++, references are a higher-level mechanism where you "refer to something", "talk about something", "look it's me right there". They are perfectly implementable as plain pointers. But as a language concept, they are a bit more amenable to be optimized away, because they are immutable. (Once a reference is set, it cannot be changed. And it refers to something -- even an object at an invalid memory location) That's why the Standard does not specify storage for references. For freedom of optimization.

UPDATE: With regards to your first doubt, main's x is a full-fledged variable (it is declared as such) and not a reference. So assigning it any other value will not change y's value. In C++, when you evaluate a reference in an expression, like so:

int x = 0;
int& y = x;

// Right hand side is the evaluation of the reference y
int z = y;

It gets evaluated to the value of the referred-to variable, i.e. the value of x, i.e. 0. And z is a variable that is distinct from x.

With regards to your third doubt, func2 will return a reference. When a function is declared as returning a reference, what it returns is a reference. A reference is something that says "I'm this other one over there". In the case of the return value, at assembler level, provided that the function is not inlined and the call really happens, and so on, what will most probably be returned by func1 or func2 will be a pointer to the referred to-variable. Actually, in C++, a reference to an int is the type of what you get by defererencing an int pointer with *. Compare the previous example code with the same code with pointers.

int x = 0;
int* const y = &x;

int z = *y;

With references, the & and * occur silently.

Just so you know, references have been introduced into the language to support operator overloading, especially the assignment operator.

// Quizz : what is the type of (b = A(123))? What if it is a 1MB object?
// What should be the type of the right-hand side of the assignment operator?
A a, b;
a = b = A(123);

It can't be a value or it would be performing horrendously bad (passing result by copy). It has to be some kind of pointer, but it can't be. There would be &s or *s somewhere, depending on how you word the Standand for the functionality. Instead of inventing lots of special typesystem cases of operator overloading, Stroustrup decided to provide two orthogonal functionality: references, which are syntax-fussless immutable pointers (and the type of "talking about a variable"), and operator overloading which is cleanly enabled by references.

Laurent LA RIZZA
  • 2,905
  • 1
  • 23
  • 41
  • You have explained my second doubt and I got it but my first and third doubt is still a mystery for me. Further with refrence to your second para, if there will be any changes in main's x ,will it also get reflected in y, i.e wether the func2 will return value or refrence(this is part of my doubt only)..please resolve my unsolved doubts also – Learner Jun 19 '14 at 04:48
  • Updated with regards to your doubts. – Laurent LA RIZZA Jun 19 '14 at 07:30
  • Just to Clarify in the famous concept of returning "functions returning the object by reference " the object to be returned should be the one whose lifetime will be more than the execution of the called function i.e will be in memory even after the execution of called function or it can be a reference variable pointing to the some type of above mentioned object... Am I right?? – Learner Jun 19 '14 at 12:03
  • Yes. Same type, or a subclass thereof. With lesser constness. (i.e. you can't refer to a `const` object with a non-`const` reference)This is all just common sense. – Laurent LA RIZZA Jun 19 '14 at 12:08
  • And maybe you should not say "functions returning the object by reference", but "functions returning a reference to an object". It's really a reference that you're returning. Not an object. – Laurent LA RIZZA Jun 19 '14 at 12:13
0

A reference is a way to make two names alias the same memory. Take this function for example:

void something_cpp(int &x)
{
    x = 2;
}

You can think of this in C terms as the following:

void something_c(int *x)
{
    *x = 2;
}

similarly a function returning a reference in c++:

int something[10];

int &something2_cpp(void)
{
    return something[0];
}

int main(int argc, char *argv[])
{
    something2_cpp() = 10;
}

Can be thought of like this in C:

int something[10];

int *something2_c(void)
{
    return &something[0];
}

int main(int argc, char *argv[])
{
    *something2_c() = 10;
}
user3736255
  • 121
  • 2