This page says a strange thing :-

The temporaries are created only if your program does not copy the return value to an object and example given is

UDT Func1(); // Declare a function that returns a user-defined type.
            ...

Func1();        //  Call Func1, but discard return value.
               //  A temporary object is created to store the return
              //   value

but if i have done :-

UDT obj=Fuct1;

It appears to me that it will also create a temporary as follow:-

Func() constructs a local object. Next, this local object is copy-constructed on the caller's stack, making a temporary object that is used as the argument of obj's copy-constructor.

Am I wrong?
Is this has something to do with copy elision?

有帮助吗?

解决方案

The page you cite it a description of the behavior of a specific compiler. Formally: the return value is always a temporary. In contexts where that temporary is used as the argument of a copy constructor (the object is copied), the standard gives explicit authorization for the compiler to elide the copy, “merging” the temporary with the named variable it is initializing. All the sentence you quote is saying is that this specific compiler always does his optimization (as do most other compilers).

其他提示

This page is Microsoft specific. It's true that the standard permits to do two, one or zero calls to the copy constructor during function return (this is called copy elision). In fact one call is always sufficient.

Suppose you write:

A f(int x) {
    return A(x);
}

void g() {
    A r = f(10);
}

The way MSVC implements this is:

void f_impl(A* r, int x) {
    new((void*)r) A(x); // construct the return value into r
}

void g_impl() {
    A r = __uninitialized__;
    f_impl(&r, 10);
}

Here you see zero calls to the copy constructor and no temporaries.

If you call f like this:

void g() {
    f(10);
}

Then the compiler still needs to construct the return value somewhere, so it creates a temporary:

void g_impl() {
    A r = __uninitialized__;
    f_impl(&r, 10);
    r.~A(); // destruct temporary
}

When it calls the copy constructor? In the implementation of f when it can't know which f's local will be returned. E.g. this:

A f(int x)
{
    A r1;
    A r2;
    // ...do something complicated modifying both r1 and r2...
    if(x)
        return r1;
    // ...do something complicated...
    return r2;
}

Is translated to something like this:

void f_impl(A* r, int x)
{
    A r1;
    A r2;
    // ...do something complicated modifying both r1 and r2...
    if(x)
    {
        new((void*)r) A(r1); // copy construct r1
        return;
    }
    // ...do something complicated...
    new((void*)r) A(r2); // copy construct r2
}

The return value is always a temporary. In the second case, a copy of that temporary (move in C++11) is made if copy elision cannot occur.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top