public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* elided copy constructors
@ 1999-03-19 14:23 E. Robert Tisdale
       [not found] ` < 36F2CDC1.8B4FEC4A@netwood.net >
  1999-03-31 23:46 ` E. Robert Tisdale
  0 siblings, 2 replies; 28+ messages in thread
From: E. Robert Tisdale @ 1999-03-19 14:23 UTC (permalink / raw)
  To: egcs

My egcs-2.90.29 980515 (egcs-1.0.3 release) compiler 
does not always elide copy constructors as permitted
by the ANSI C++ standard so I must devise a workaround
to void a costly copy of doomed objects which
won't be referenced again until they are destroyed.
The following test program illustrates the problem:

----------------------------------------------------------------------
// test.cc

#include<iostream>

class X {                       // a dynamic array class
  // representation
  int*  p;                      // pointer to a huge array
  int   n;                      // length of the huge array
  // constructors
  X(int* q, int k):             // private constructor definition
    p(q), n(k) { }
  public:
  explicit
  X(int k):                     // explicit constructor definition
    p(new int[k]), n(k) { }
  X(const X& x);                // copy constructor declaration
 ~X(void) {                     // destructor definition
    if (p) delete [] p; }
  // functions
  int   length(void) const { return n; }
  friend                        // salvage a doomed array
  X     salvage(X& x) { int* q = x.p; x.p = 0; return X(q, x.n); }
  // operators
  const
  int&  operator [](int j) const { return p[j]; }
  int&  operator [](int j)       { return p[j]; }
  };

X::X(const X& x):               // copy constructor definition
  p(new int[x.n]), n(x.n) {
  cerr << "The copy constructor was called!" << endl;
  for (int j = 0; j < n; j++)   // copy the array
    p[j] = x.p[j];
  }

// user defined functions

#define salvage(x) x
#define return(x) return salvage(x)

inline
X       f0(int n) {
  cerr << "The copy constructor may be called for f0(int)." << endl;
  return X(n);
  }
inline
X       f1(int n) {
  X     x(n);
  for (int j = 0; j < n; j++)   // Initialize x.
    x[j] = j;
  cerr << "The copy constructor may be called for f1(int)." << endl;
  return(x);
 }
inline
X       g0(X x) {
  cerr << "The copy constructor may be called for g0(X)." << endl;
  return salvage(x);
  }
inline
X       g1(const X& x) {
  cerr << "The copy constructor must be called for g1(const X&)." << endl;
  return x;
  }

int
main () {
  cerr << endl
       << "The copy constructor may be called for X x0 = f0(32);" << endl;
  X x0 = f0(32);
  cerr << endl
       << "The copy constructor may be called for X x1 = f1(32);" << endl;
  X x1 = f1(32);
  cerr << endl
       << "The copy constructor may be called for X y0 = g0(f0(32));" << endl;
  X y0 = g0(f0(32));
  cerr << endl
       << "The copy constructor may be called for X y1 = g1(x1);" << endl;
  X y1 = g1(x1);

  cerr << endl
       << "The copy constructor must be called for X z0 = y0;" << endl;
  X z0 = y0;
  return 0;
  }
----------------------------------------------------------------------

I compiled and ran `test' as follows:

----------------------------------------------------------------------
$ uname -rms
Linux 2.0.36 i686
$ g++ --version
egcs-2.90.29 980515 (egcs-1.0.3 release)
$ g++ -O2 -felide-constructors -o test test.cc
./test

The copy constructor may be called for X x0 = f0(32);
The copy constructor may be called for f0(int).

The copy constructor may be called for X x1 = f1(32);
The copy constructor may be called for f1(int).
The copy constructor was called!

The copy constructor may be called for X y0 = g0(f0(32));
The copy constructor may be called for f0(int).
The copy constructor may be called for g0(X).
The copy constructor was called!

The copy constructor may be called for X y1 = g1(x1);
The copy constructor must be called for g1(const X&).
The copy constructor was called!

The copy constructor must be called for X z0 = y0;
The copy constructor was called!
$ 
----------------------------------------------------------------------

After editing the `test.cc' source file
to comment out the first C preprocessor macro definition

// #define salvage(x) x

I compiled and ran `test' again as follows:

----------------------------------------------------------------------
$ g++ -O2 -felide-constructors -o test test.cc
$ ./test

The copy constructor may be called for X x0 = f0(32);
The copy constructor may be called for f0(int).

The copy constructor may be called for X x1 = f1(32);
The copy constructor may be called for f1(int).

The copy constructor may be called for X y0 = g0(f0(32));
The copy constructor may be called for f0(int).
The copy constructor may be called for g0(X).

The copy constructor may be called for X y1 = g1(x1);
The copy constructor must be called for g1(const X&).
The copy constructor was called!

The copy constructor must be called for X z0 = y0;
The copy constructor was called!
[edwin@localhost svmt]$ 
----------------------------------------------------------------------

Perhaps I shouldn't expect my C++ compiler to elide
the copy constructor in function g0(X) if it wasn't inline'd
but it I think that the C++ compiler should recognize
that x in function f1(int) is a reference to the return value
and initialize the return value with X(n)
instead of creating a temporary and copying it
to the return value upon return from f1(int).

My question is, "When should we expect the egcs compiler
to elide copy constructors as permitted by the standard?"

Meanwhile, I am interested in comments and suggestions
concerning workarounds.

Yes, I really do need to return by value.
No, I really don't want to do reference counting.
I am developing class libraries for application programmers

        http://www.netwood.net/~edwin/svmt/

The class library need not be portable but application programmers
should be able to write portable applications without worrying
about whether copy constructors are elided or not.

Thanks in advance, E. Robert Tisdale <edwin@netwood.net>

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~1999-03-31 23:46 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-03-19 14:23 elided copy constructors E. Robert Tisdale
     [not found] ` < 36F2CDC1.8B4FEC4A@netwood.net >
1999-03-19 15:18   ` Martin v. Loewis
     [not found]     ` < 199903192313.AAA00798@mira.isdn.cs.tu-berlin.de >
1999-03-19 15:54       ` Mark Mitchell
     [not found]         ` < 199903192356.PAA03038@adsl-206-170-148-33.dsl.pacbell.net >
1999-03-19 19:20           ` Tim Hollebeek
1999-03-31 23:46             ` Tim Hollebeek
1999-03-20  6:26           ` espie
     [not found]             ` < 19990320142609.15873.qmail@quatramaran.ens.fr >
1999-03-20  7:18               ` Martin v. Loewis
     [not found]                 ` < 199903201510.QAA08826@mira.isdn.cs.tu-berlin.de >
1999-03-20  9:50                   ` Mark Mitchell
     [not found]                     ` < 199903201752.JAA04517@adsl-206-170-148-33.dsl.pacbell.net >
1999-03-20 11:16                       ` craig
1999-03-31 23:46                         ` craig
1999-03-31 23:46                     ` Mark Mitchell
1999-03-31 23:46                 ` Martin v. Loewis
1999-03-31 23:46             ` espie
1999-03-21  6:09           ` Gerald Pfeifer
1999-03-28  9:45             ` Mark Mitchell
1999-03-29 12:50               ` Gerald Pfeifer
1999-03-31 23:46                 ` Gerald Pfeifer
1999-03-31 23:46               ` Mark Mitchell
1999-03-31 23:46             ` Gerald Pfeifer
1999-03-21  8:41           ` New webpage? Providing egcs support Gerald Pfeifer
     [not found]             ` < Pine.GSO.4.10.9903211733410.1651-100000@markab.dbai.tuwien.ac.at >
1999-03-21  9:38               ` Mark Mitchell
1999-03-31 23:46                 ` Mark Mitchell
1999-03-21 11:08               ` Jeffrey A Law
1999-03-31 23:46                 ` Jeffrey A Law
1999-03-31 23:46             ` Gerald Pfeifer
1999-03-31 23:46         ` elided copy constructors Mark Mitchell
1999-03-31 23:46     ` Martin v. Loewis
1999-03-31 23:46 ` E. Robert Tisdale

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).