This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c++/5995: double call of copy constructor
- From: martin dot gerbershagen at icn dot siemens dot de
- To: gcc-gnats at gcc dot gnu dot org
- Date: 18 Mar 2002 11:11:12 -0000
- Subject: c++/5995: double call of copy constructor
- Reply-to: martin dot gerbershagen at icn dot siemens dot de
>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;
}