3

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

2
  • @jrok - From the FAQ "one of their engineers told me that they found this return-by-value optimization to be so fast that you get it even if you don't compile with optimization turned on" so apparently that's not necessarily true. It may vary from compiler to compiler. Commented May 11, 2012 at 12:41
  • @Benj Indeed, in tried with gcc and there's no copy even without optimisations. Commented May 11, 2012 at 12:45

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

Comments

3

Take a look at return value optimisation which is a common optimisation to avoid constructor calls.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.