From: suresh on
Hi

In the following code, I expect the copy constructor to be called as
per the textbooks but it is not being called. Could you please tell me
why? g++ version 4.1.2

# include <iostream>
using namespace std;
class base
{
char s;
public:
base( ){cout<< "construction" << endl;}
base(const char a ) {cout << "construction with arg" << endl;}
base(const base & a){cout <<"copy constructor" << endl;}
base & operator=(const base & a){cout << "assignment operator" <<
endl;}
~base( ) {cout << "destruction" << endl;}
};

main ( )
{
base b1 = 'x'; //why copy constructor not called here?
base b2 = b1; //copy constructor is called
}

the line base b1 = 'x', as per my understanding must create a
temporary object and then it should be copied to b1. But only the
constructor with argument is called in this example when executed.

Could you please explain why?

thanks and regards
suresh


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: dimitry.ivanov on
On Apr 15, 2:33 pm, suresh <suresh.amritap...(a)gmail.com> wrote:
> Hi
>
> In the following code, I expect the copy constructor to be called as
> per the textbooks but it is not being called. Could you please tell me
> why? g++ version 4.1.2
>
<skip>

> main ( )
> {
> base b1 = 'x'; //why copy constructor not called here?

<skip>

> Could you please explain why?

I think compiler just optimized base b1='x'; to base b1('x');


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: d04rp on

> In the following code, I expect the copy constructor to be called as
> per the textbooks but it is not being called. Could you please tell me
> why? g++ version 4.1.2
>
> # include <iostream>
> using namespace std;
> class base
> {
> char s;
> public:
> base( ){cout<< "construction" << endl;}
> base(const char a ) {cout << "construction with arg" << endl;}
> base(const base & a){cout <<"copy constructor" << endl;}
> base & operator=(const base & a){cout << "assignment operator" <<
> endl;}
> ~base( ) {cout << "destruction" << endl;}
>
> };
>
> main ( )
> {
> base b1 = 'x'; //why copy constructor not called here?
> base b2 = b1; //copy constructor is called
>
> }
>
> the line base b1 = 'x', as per my understanding must create a
> temporary object and then it should be copied to b1. But only the
> constructor with argument is called in this example when executed.
>
> Could you please explain why?

It must not create a temporary object. Because one of the constructors
take an char, that constructor will be called.
base b1 = 'x' is equivalent with base b1('x'); (so it no assignment is
taking place).


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: David Pol on
On 15 abr, 20:33, suresh <suresh.amritap...(a)gmail.com> wrote:
> Hi
>
> In the following code, I expect the copy constructor to be called as
> per the textbooks but it is not being called. Could you please tell me
> why? g++ version 4.1.2
>
> # include <iostream>
> using namespace std;
> class base
> {
> char s;
> public:
> base( ){cout<< "construction" << endl;}
> base(const char a ) {cout << "construction with arg" << endl;}
> base(const base & a){cout <<"copy constructor" << endl;}
> base & operator=(const base & a){cout << "assignment operator" <<
> endl;}
> ~base( ) {cout << "destruction" << endl;}
>
> };
>
> main ( )
> {
> base b1 = 'x'; //why copy constructor not called here?
> base b2 = b1; //copy constructor is called
>
> }
>
> the line base b1 = 'x', as per my understanding must create a
> temporary object and then it should be copied to b1. But only the
> constructor with argument is called in this example when executed.
>
> Could you please explain why?

Hello,

Indeed,

base b1 = 'x';

should construct a temporary object of type base using the constructor
of base that takes a const char argument, and then copy it into b1.
But the compiler is allowed to elide the call to the copy constructor
of base in order to generate more optimal code:

base b1('x');

Note that the compiler is still required to check whether the elided
copy constructor is accessible or not.

Regards,
David

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Chris Uzdavinis on
On Apr 15, 2:33 pm, suresh <suresh.amritap...(a)gmail.com> wrote:

> class base
> {
> char s;
> public:
> base(const char a ) {cout << "construction with arg" << endl;}
> base(const base & a){cout <<"copy constructor" << endl;}
> base & operator=(const base & a){cout << "op=" << endl;}
> ~base( ) {cout << "destruction" << endl;}
> };

> base b1 = 'x'; //why copy constructor not called here?

The standard allows for compilers to not create the temporary, and
instead directly construct the object from the argument. Consider it
an optimization. Note, though, that since it may have different
runtime behavior than if the temporary were created, it's not a
transparent optimization. (Imagine the copy constructor having
visible side effects... with this optimized away they will not occur.
This is allowable behavior, but suggests we should not have
dependencies upon externally visible side effects occurring in copy
constructors!)

That said, the code still must compile AS IF it were creating a
temporary and using the copy constructor--even if it doesn't actually
call the copy constructor. For example, if you made the copy
constructor private, then the code should not compile, regardless if
this optimization exists in your compiler or not. Clearly, the
correctness of code should not depend on an optimization!

So logically the temporary is always created and then copied. The
rules of C++ require that this be a valid calling sequence, even if
physically, it does not actually happen.

> base b2 = b1; //copy constructor is called

This is not creating the temporary either. Instead, it is directly
constructing b2 by using the copy constructor.

> the line base b1 = 'x', as per my understanding must create a
> temporary object and then it should be copied to b1. But only the
> constructor with argument is called in this example when executed.

Your understanding is not quite right. "Must" is too strong of a
word. "May" is better, but since most compilers prefer to generate
good code, "probably doesn't" is a better description.


Hope this helps.

Chris

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]