temporary objects?

How do you know when temporary objects are created? For instance I was reading a webpage that said when you are creating a new string, for instance called newStr from 2 other strings, when the string constructor is called, a temporary object is created that contains the 2 previous strings together. Then the newStr object will copy from that temporary object.

But when else does this happen. I have found somewhere else that says when an expression such as a = b + c + d. That when this is evaluated, c + d creates a temp object, then b + that temp creates another temp, and then a = that new temp.

Are temp objects created when passing to functions, if so is it the same for by value and by reference? Are they created when variables are being passed to all constructors?
temp objects are created when the compiler can't find any other way around it to do the work, is the useless answer.

passing to constructors should be by reference, so no, that should not create a temp. Same for any other function (constructors are not special here). Pass by value creates a *copy* but not a temporary.
look
void foo(thing x); //x is of type thing. x is not a 'temporary' because it has a name you can see. its name is x! But, foo(y) copies y into x, which may be expensive. Better if it were a reference or constant reference so foo(y) does not copy, it is just made accessible as y directly.

a temporary has no name.
so lets see.. (a+b).print(); //temporary created, and used to invoke its print function. But after this statement, the temporary is gone...
functions that return an object can be used that way


foo().memberfunction();

not all temps are bad. The trick is avoiding the ones that can be avoided when it matters. The same is true of copying when you don't need to: avoid it.

I know this is kind of rambly and a poor answer.
Last edited on
See object lifetime (note section on temporary object lifetime):
https://en.cppreference.com/w/cpp/language/lifetime

You may also need to refresh your understanding of value categories:
https://en.cppreference.com/w/cpp/language/value_category

Note also copy elision:
https://en.cppreference.com/w/cpp/language/copy_elision
> I have found somewhere else that says when an expression such as a = b + c + d.
> That when this is evaluated, c + d creates a temp object, then b + that temp creates another temp,
> and then a = that new temp.

If a, b, c, d are of a scalar type (say int), this is not correct. For instance, the value of c+d needs to be computed; the code for doing that is generated; but no temporary object is created; there is no temporary materialisation.
Temporary materialisation: https://en.cppreference.com/w/cpp/language/implicit_conversion#Temporary_materialization


> Are temp objects created when passing to functions, if so is it the same for by value and by reference?
> Are they created when variables are being passed to all constructors?

Scott Myers in 'More Effective C++':
True temporary objects in C++ are invisible - they don't appear in your source code. They arise whenever a non-heap object is created but not named. Such unnamed objects usually arise in one of two situations: when implicit type conversions are applied to make function calls succeed and when functions return objects.

Consider first the case in which temporary objects are created to make function calls succeed. This happens when the type of object passed to a function is not the same as the type of the parameter to which it is being bound. These conversions occur only when passing objects by value or when passing to a reference-to-const parameter. They do not occur when passing an object to a reference-to-non-const parameter.

The second set of circumstances under which temporary objects are created is when a function returns an object. Anytime you see a reference-to-const parameter, the possibility exists that a temporary will be created to bind to that parameter. Anytime you see a function returning an object, a temporary will be created (and later destroyed).



A good optimiser can exploit the as-if rule and optimise away creation of temporaries if the creation (and destruction) of these do not affect the observable behaviour of the program.
The as-if rule: https://en.cppreference.com/w/cpp/language/as_if

For instance, several temporaries could be created for this code fragment (binding references to prvalues, member access on a class prvalue, array subscripting, discarded value expression). But the optimiser knowns what is going on and can exploit the as-if rule to avoid the creation of needless temporaries (even when the standard allows them to be created).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct A 
{
    char arr[3] {};
    A( int v ) : arr{ char(v), char(v+1), char(v+2) } {}
    int bar() const { return arr[1] - arr[0] ; }
};

void foo( int& n )
{
    const int& n1 = n - 2 ;
    const int& n2 = 1 - n ;
    const int& n3 = A(7).bar() ;
    n += n1 + n2 + n3 ;    
}

void foo_optimised( int& ) { /* nothing */ }


https://gcc.godbolt.org/z/YTnhhP

I would suggest that at this stage do not worry excessively about the impact of temporaries on performance; focus on writing clean, maintainable, correct code and let the optimiser do what it does best.
Topic archived. No new replies allowed.