This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

c++/5995: double call of copy constructor



>Number:         5995
>Category:       c++
>Synopsis:       double call of copy constructor
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 18 03:16:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Martin Gerbershagen
>Release:        g++-3.0.3
>Organization:
>Environment:
sparc-sun-solaris2.6
>Description:
The attached test program x.C generates the following output:

O::O()
o1(getOcopy())
O::O(const O& s)
O::O(const O& s)
O::~O()
o2(getOref())
O::O(const O& s)
&o3(getOref())
o4 = getOref()
O::O(const O& s)
&o5 = getOcopy()
O::O(const O& s)
o6 = getOcopy()
O::O(const O& s)
o7 = getOcopy()
O::O()
O::O(const O& s)
O::operator=
O::~O()
o7 = getOref()
O::operator=
(void)getOcopy()
O::O(const O& s)
O::~O()
end
O::~O()
O::~O()
O::~O()
O::~O()
O::~O()
O::~O()
O::~O()

The output shows, that the copy constructor of O is called
twice during the initialization of o1. This should not be the case and can result in performance degradation, if the class used has complex members. The test program works
properly, if it is compiled with g++ 2.95.3.
>How-To-Repeat:
g++ -O x.C && a.out
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="x.C"
Content-Disposition: inline; filename="x.C"

#include <iostream.h>

class O {
public:
   O& operator=(const O&);
   O(const O&);
   O();
   ~O();
};

O& O::operator=(const O& s)
{
   cout << "O::operator=" << endl;
   if (this != &s) {
   }
   return *this;
}

O::O(const O& s)
{
   cout << "O::O(const O& s)" << endl;
}

O::O()
{
   cout << "O::O()" << endl;
}

O::~O()
{
   cout << "O::~O()" << endl;
}

class A {
   O o;
public:
   O getOcopy() const;
   const O& getOref() const;
   A& operator=(const A&);
   A(const A&);
   A();
   ~A();
};

inline O A::getOcopy() const {
   return o;
}

inline const O& A::getOref() const {
   return o;
}

A& A::operator=(const A& s)
{
   if (this != &s) {
      o = s.o;
   }
   return *this;
}

A::A(const A& s):
   o(s.o) {
}

A::A()
{
}

A::~A()
{
}


int main() {
   A a;
   cout << "o1(getOcopy())" << endl;
   O o1(a.getOcopy());

   cout << "o2(getOref())" << endl;
   O o2(a.getOref());

   cout << "&o3(getOref())" << endl;
   const O &o3(a.getOref());

   cout << "o4 = getOref()" << endl;
   O o4 = a.getOref();

   cout << "&o5 = getOcopy()" << endl;
   const O &o5 = a.getOcopy();

   cout << "o6 = getOcopy()" << endl;
   O o6 = a.getOcopy();

   cout << "o7 = getOcopy()" << endl;
   O o7;
   o7 = a.getOcopy();

   cout << "o7 = getOref()" << endl;
   o7 = a.getOref();

   cout << "(void)getOcopy()" << endl;
   a.getOcopy();

   cout << "end" << endl;
   return 0;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]