Topic: FW: Inherent C++ problem?


Author: Eugene Lazutkin <eugene@int.com>
Date: 1996/01/19
Raw View
----------
From:  Max Motovilov[SMTP:max@int.com]
Sent:  Friday, January 19, 1996 4:01 PM
To:  'Eugene Lazutkin'
Subject:  (for comp.std.c++)  Inherent C++ problem?

Looks like Subj to me, but maybe I misunderstand something or overlooking a
simple workaround...

Here is the example:

 struct Complex
 {
  double re, im;

  Complex( double r, double i ) : re( r ), im( i ) {}
  Complex( const Complex& c ) : re( c.re ), im( c.im ) {}
 };

 Complex operator + ( const Complex& a, const Complex& b )
 {
  return Complex( a.re+b.re, a.im+b.im );
 }

It is all right by now. Consider the following use then:

 Complex a( 1, 0 ), b( 0, 1 );
 Complex c( a+b );

In the last line 3 objects of type Complex are constructed instead of 1,
namely:

1) Temporary Complex object constructed in 'operator +'
2) Return value of 'operator +' copy-constructed from (1)
3) 'c', copy-constructed from (2)

This is inefficient to the last extreme, moreover it cannot even be
optimized out since any copy-constructor can theoretically have non-local
side effects....

To me, the step (2) can be eliminated by certain amendment to the semantics
of the language while (3) seems to be inherent. I wonder though if
something could be done about it within the bounds of the current
standard...

Regards,
...Max...
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: ark@research.att.com (Andrew Koenig)
Date: 1996/01/22
Raw View
In article <01BAE696.8C249300@dino.int.com> Eugene Lazutkin <eugene@int.com> writes:

>  Complex c( a+b );

> In the last line 3 objects of type Complex are constructed instead of 1,
> namely:

> 1) Temporary Complex object constructed in 'operator +'
> 2) Return value of 'operator +' copy-constructed from (1)
> 3) 'c', copy-constructed from (2)

> This is inefficient to the last extreme, moreover it cannot even be
> optimized out since any copy-constructor can theoretically have non-local
> side effects....

But it can be optimized -- essentially the implementation is permitted
to assume that the copy constructor does not have any important
side effects.  Moreover, lots of implementations perform this kind
of optimization.
--
    --Andrew Koenig
      ark@research.att.com
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: Etay_Bogner@mail.stil.scitex.com (Etay Bogner)
Date: 1996/01/22
Raw View
In article <01BAE696.8C249300@dino.int.com>, Eugene Lazutkin
<eugene@int.com> wrote:

>> ----------
>> From:   Max Motovilov[SMTP:max@int.com]
>> Sent:   Friday, January 19, 1996 4:01 PM
>> To:     'Eugene Lazutkin'
>> Subject:        (for comp.std.c++)  Inherent C++ problem?
>>
>> It is all right by now. Consider the following use then:
>>
>>         Complex a( 1, 0 ), b( 0, 1 );
>>         Complex c( a+b );
>>
>> In the last line 3 objects of type Complex are constructed instead of 1,
>> namely:
>>
>> 1) Temporary Complex object constructed in 'operator +'
>> 2) Return value of 'operator +' copy-constructed from (1)
>> 3) 'c', copy-constructed from (2)
>>

For simplicity, let's write this as :

Complex callee() {
    return Complex(0,0);
    }

void caller() {
    Complex a = callee(); // which is basically the same as a(callee())
    }

There are two points of interest :
1) the "caller" function
2) the "callee" function

Let's see what the compilers knows at each point :

1) the compiler knows it's going to call a function the returns an object.
So it might make some space on the stack for the returned object and put a
pointer to this space somewhere in the argument list to the "callee()"
function.

2) the compiler know that this function is going to return an object, so
it expects to find a pointer to place the newly created in. it indeed
creates a new object but it directly creates it in the "callee()" stack
space.

So now the, your example is actually doing only one step :

operator+ create the newly created "a+b" object directly in c.

--
-- Etay Bogner,
-- Etay_Bogner@mail.stil.scitex.com,
-- Scitex Corp.
-- Israel.
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]