c++ simple allocation by a function

allocation, c++

Solution

The format semantics of:

Test other = toto();

involve several copies (but no assignment). The compiler is allowed to elide all of the different instances, however, which eliminates the copies; almost all compilers do do this optimization.

More concretely, the standard doesn't specify where values of class type are returned, but the usual solution is for the caller to allocate the space, and pass a hidden pointer to it into the function. Without the above mentionned optimizations:

Test
toto()
{
    Test t;
    return t;
}

would result in the local variable `t` being constructed, then the return statement would copy `t` into the space pointed to by the hidden pointer. The optimization (called named return value optimization, or NRVO) here results in the compiler using the space pointed to by the hidden pointer for `t`, rather than creating a separate `t` locally. (Obviously, when it does this, it does not destruct `t`, as it would otherwise after the copy.)

In the declaration:

Test t = toto();

, the formal semantics would have the compiler allocate the space for a temporary of type Test, pass the address of this space as the hidden pointer to `toto`, then copy this temporary into `t` and destruct it. The optimization here consists in the compiler passing the address of `t` directly to `toto`, eliding the intermediate temporary.

Problem

I tried to understand how this allocation works in c++ : ``` Test other = toto(); ``` This is the full code source : ``` #include <iostream> class Test { public: Test() { j = i++; std::cout<<"default constructor "<<j<<std::endl; } Test(const Test&) { std::cout<<"constuctor by copy "<<j<<std::endl; } Test & operator=(const Test&) { std::cout<<"operator = "<<j<<std::endl; return *this; } int j; static int i; }; int Test::i = 0; Test toto() { Test t; return t; } int main() { Test other = toto(); std::cout<<other.j<<std::endl; Test another; return 0; } ``` The code not used constructor by copy or operator =, so I don't understand really how it's works ... I used gcc 4.7.0 Thranks for your help :) Jerome

Original source