Home > Software design >  Returning reference to a local static variable
Returning reference to a local static variable

Time:08-13

Just started learning c and came across this example where the function is returning a reference to a local static variable.

int& fun() {
    static int x = 10;
    return x;
}

int main() {
    int &z = fun();
    cout << fun() << " ";
    z = 30;
    cout << fun();
    return 0;
}

What does the line int &z = fun(); do? Are we storing a reference inside another reference? I'm new to the language and all I know is that reference variables refer to a variable just like an alias. Can anyone explain how this works?

CodePudding user response:

Are we storing a reference inside another reference?

No, references aren't even required to have "storage". A reference is something to simplify programming. auto& thing = foo.get_value_reference(); and then using thing makes code easier to write and debug. thing doesn't even have to exist as a separate entity when you look at the final assembly code.

int orig;
int& a = orig;
int& b = a;

b is now a reference to orig - nothing else. You can't reference a reference.

CodePudding user response:

Are we storing a reference inside another reference?

No, there is no reference to reference, at least in C\C .

For me, a reference is just a different name for another variable, at the end, they are all referring to the same, single object. In more detail, abstractly, whenever you write int& a = b, all you have is still b, and there is no such thing called a, that ever exist. (a is just an alias of b)

Because of that, we can't have a different name of a name, that would sound a bit weird, since it does not actually refer to anything that exist.

In your case above, what int& fun() does is returning the actual static int x = 10;. And int &z = fun();, once again, refer directly the the actual static int x = 10;. Whatever z or anything, afterall, it is just static int x = 10, under different names.

This would be different if you remove the amphersand-& to int fun(), which returns a copied version of int x = 10;, which means now existed two different things: int x = 10 and a copy of int x = 10.

That's why C\C is memory-efficient, isn't it? You know when things get copied and when it does not, which helps optimization a lot!

Hope this helps!

CodePudding user response:

First of all, a variable declared static inside a function is allocated when the program begins and deallocated when the program ends. We can keep a reference to it after returning from the function.

Let's consider this function:

int& fun() {
    static int x = 10;
    return x;
}

Returning a reference to the static variable x is like returning the variable itself. This lets you increment it, for instance:

  std::cout << func()   << std::endl;
  std::cout << func()   << std::endl;  # outputs 11
  std::cout << func()   << std::endl;  # outputs 12

This is not possible if you're just returning the value of the variable.

int &z = fun() lets you refer to that same static variable through the name z in the same way:

  int &z = fun();
  std::cout << z   << std::endl;
  std::cout << z   << std::endl;  # outputs 11
  std::cout << z   << std::endl;  # outputs 12

This idiom of having a function return a static variable (by reference or otherwise) can be used to guarantee when a "global" variable is initialized. The language guarantee that a static variable is initialized the first we pass through the declaration at runtime.

Let's consider:

int& fun() {
    static int x = 10;
    return x;
}

Here, init_x() is called the first time we call fun() to retrieve its value.

int& fun() {
    static int x = init_x();
    return x;
}
  •  Tags:  
  • c
  • Related