Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The variables addresses

Look at this code:

class Test
{
    //
};

Test TestAddress()
{
    Test test;
    cout << "Object Address in function: " << (int)&test << endl;
    return test;
}

int IntAddress()
{
    int test;
    cout << "Integer Address in function: " <<(int)&test << endl;
    return test;
}

int main() {

    int x = IntAddress();
    cout << "Integer Address in Main: " <<(int)&x << endl;

    Test object = TestAddress();
    cout << "Object Address in Main: " <<(int)&object << endl;

    return 0;
}

The output is:

Integer Address in function: 1076679252
Integer Address in Main: 1076679220
Object Address in function: 1076679221
Object Address in function: 1076679221

Could someone explain me why is that, when I'm returning an object by value I receive the same addresses in function and main. But when I do the same thing with an Integer, the adressess are different?

like image 422
Wyjun Avatar asked Jan 18 '26 06:01

Wyjun


2 Answers

I think that your compiler is applying return value optimization, where main() and TestAddress() are acting on the same object variable in memory.

like image 173
Tarc Avatar answered Jan 19 '26 18:01

Tarc


The so called "automatic variables" are allocated on the stack. The moment of their allocation can be subject to compiler optimization.

When a local variable is returned by value, the compiler has essentially two choices:

  • Allocate the variable within the function, then, at the return
    • Create a temporary and copy the variable in it and
    • Destroy the variable
  • then at the = in the caller, copy the temporary into the caller receiving constructing variable.

Or, it can:

  • see that the function local variable is the only expression used in the return statement (there is just one return, there, so that's trivial)
  • see that the return value is actually used to construct the caller variable, hence...
  • allocate only one variable in the caller space, just before the call and the function local one be a reference to it, and eliminate all the copy stuff.

Now, since the cost to "copy an integer" and of "dereferece an integer" in term of CPU processing are in favor of the copy (an int is the CPU primitive number type), and since "temporary integer" can fit a CPU register (so it's not a "copy to memory) the compiler use the first method for int's.

Since a class can have whatever size (and copy may have higher cost), the compiler can decide do adopt the second method.

In any case, you should not care about that: the external observable behavior will be the same, since the access to the external and internal variables are mutually exclusive.

like image 36
Emilio Garavaglia Avatar answered Jan 19 '26 18:01

Emilio Garavaglia



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!