1

I was studying about l-values and r-values but I am confused with this:

#include<iostream>
int& get_val(){
    return 10;
}
int main(){
    get_val() = 5;
    int a = get_val();
    std::cout<<a<<std::endl;

    return 0;
}

I know about int a = get_val(); (i.e., it will assign the returned value to the variable), but I want to know what this does: get_val() = 5;. What does int& get_val() do?

I know we cannot run this code but I want to learn the concept behind this.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • 9
    You should get an error on a modern compiler: [https://ideone.com/l8XCOx](https://ideone.com/l8XCOx) – drescherjm Apr 06 '22 at 15:54
  • 1
    Where did you find this? The code should not compile. Sounds like you could use a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – NathanOliver Apr 06 '22 at 15:55
  • 1
    If `get_val` returned a reference to some variable `foo`, then `get_val() = x` would be like `foo = x` – Wyck Apr 06 '22 at 15:56
  • After reading my previous comment I hope you can see how if `get_val` tries to return 10 it's nonsensical because it would be like assigning a value to `10`. `10 = x` doesn't make sense. So you really need a different implementation of `get_val` for this to make sense. If you saw something like this in the wild, the `get_val` almost certainly returned a reference to some other variable or storage location. – Wyck Apr 06 '22 at 16:00
  • Read https://stackoverflow.com/questions/1565600 for a comprehensive explanation of what's going on here. – cigien Apr 06 '22 at 16:21
  • 1
    "I know we cannot run this code but I want to learn the concept behind this" - This is a weird way of approaching things. "I know this doesn't work, but I want to know how it works." It doesn't. That's the point. – Sebastian Redl Apr 06 '22 at 16:25

1 Answers1

8

Your get_val function is defined as returning a reference to an integer; however, what you actually return is a reference to a constant, so any attempt to assign a value to that will not compile. In fact, the function itself (attempting to return a reference to 10) won't compile; clang-cl gives this:

error : non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'

However, if you add a static int1 inside your function, and return (a reference to) that, then you can use statements like getval() = x; to assign the value of x to that internal static int (which is otherwise 'invisible' outside the function).

Here's a short demonstration:

#include <iostream>

int& get_val()
{
    static int inside = 42;
    std::cout << inside << "\n";
    return inside;
}

int main()
{
    get_val() = 5; // Prints INITIAL value of "inside" then (after the call) assigns
                   // the value 5 to it, via the returned reference
    get_val();     // Prints the modified value
    return 0;
}

The above example is trivial and would likely not serve any real-world purpose; it is purely for demonstration purposes. However, there may be cases where you would want a function to return a reference to any one of a number of different objects, depending on calculations and decisions made in that function; the selected, referenced object can then be suitably modified using code like that shown here.


1 The inside variable needs to be declared as static so that:

  1. Its lifetime does not end when the function returns (thus creating a dangling reference).
  2. Its value is maintained from one call to the next.
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83