2

I found a bit of confusion in the ways a variable is constructed, copied, assigned because in the compilers I tried they usually apply some kind of optimization (remove temporary etc.).

I'm listing the different ways I tried and the output of my program in comments below. May be some of them included temporary object creation but are optimized away by the compiler? Please mention if the output is correct as per the standard and what is the output if no optimizations are applied.

#include <iostream>
using namespace std;

class type {
    public:
    type(int z){cout << "ctor"<<endl;};
    type(const type&){cout<<"copy"<<endl;}
    void operator=(const type& ){cout <<"assign"<<endl;}
};
int main()
{
//constructor
type c(8);         //ctor 
type c2{8};        //ctor 
type c3 = 8;       //ctor  
type c4 = {8};     //ctor
type c5 = type(8); //ctor
type c6 = type{8}; //ctor
cout <<endl; 

//copy 
type ci0(c);        //copy
type ci1{c};        //copy
type ci2 = c;       //copy
type ci3 = {c};     //copy
type ci4 = type(c); //copy
type ci5 = type{c}; //copy
cout <<endl;

//assign
c2 = c;        //assign
c2 = {c};      //assign
c2 = type{c};  //copy and then assign
c2 = type(c);  //copy and then assign
c2 = 8;        //ctor and then assign
c2 = {8};      //ctor and then assign
c2 = type(8);  //ctor and then assign
c2 = type{8};  //ctor and then assign
}
pasha
  • 2,035
  • 20
  • 34
  • 1
    You can also create a copy of an object by using: `type ci4 = {c}`, `type ci5 = type{c}` and `type ci6 = type(c)`. – Ruks Aug 13 '21 at 02:32
  • Much of what you label copy is not copy but merely constructor. And some of what you cable ctor is technically ctor, then assignment. However the compiler i – Joe Aug 13 '21 at 02:33
  • @Joe All 3 lines labelled `copy` would invoke a copy constructor, so what are you trying to say? – sweenish Aug 13 '21 at 02:34
  • 2
    Please try to focus the question more. You're asking about a set of features that is very large and contains lots of special cases. In its current form, I don't think this question is suitable. Is there some specific case that you're unclear about? – cigien Aug 13 '21 at 02:36
  • Sorry my comment was posted inadvertently before I finished it. I would suggest reading up on the difference between l-values and r-values. Today, compilers that recognize r-values can optimize what used to be construction, then assignment into simply construction – Joe Aug 13 '21 at 02:37
  • @cigien, let me just be specific about the ones I've tried and also let me include Ruks' mentioned (thanks btw Ruks) – pasha Aug 13 '21 at 02:43
  • Does this answer your question? [What are copy elision and return value optimization?](https://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization) – xskxzr Aug 13 '21 at 05:12
  • @xskxzr, i edited the question, i just want to know what is the output if there are no optimizations applied. – pasha Aug 13 '21 at 08:23
  • Copy elision became mandatory in C++17, it's no longer an "optimization". – HolyBlackCat Aug 13 '21 at 08:25

1 Answers1

0

Using explicit to ctor and copy ctor and deleting each of the functions, I was able to get below results.

//constructor
type c(8);         //explicit ctor 
type c2{8};        //explicit ctor 
type c3 = 8;       //implicit ctor, explicit copy  
type c4 = {8};     //implicit ctor
type c5 = type(8); //explicit ctor, implicit copy
type c6 = type{8}; //explicit ctor, implicit copy
cout <<endl; 

//copy 
type ci0(c);        //explicit copy
type ci1{c};        //explicit copy
type ci2 = c;       //implicit copy
type ci3 = {c};     //implicit copy
type ci4 = type(c); //implicit copy
type ci5 = type{c}; //implicit copy
cout <<endl;

//assign
c2 = c;        //assign
c2 = {c};      //assign
c2 = type{c};  //implicit copy and then assign
c2 = type(c);  //implicit copy and then assign
c2 = 8;        //implicit ctor and then assign
c2 = {8};      //implicit ctor and then assign
c2 = type(8);  //explicit ctor and then assign
c2 = type{8};  //explicit ctor and then assign
pasha
  • 2,035
  • 20
  • 34