Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > copy constructor - optimized away or not?

Reply
Thread Tools

copy constructor - optimized away or not?

 
 
Alexander Stippler
Guest
Posts: n/a
 
      10-30-2005
The following code snippet (those of you who read my last postings
might be familiar with it ):

//--------------------------------------------------------------------
template<class Impl>
class Vector {};

template<class Ref>
class VectorView: public Vector<VectorView<Ref> >
{
Ref r;
public:
VectorView() {}
operator const Ref &() const { return r; }
operator Ref &() { return r; }
};

template<class T>
class DenseVector: public Vector<DenseVector<T> >
{
public:
DenseVector() {}

DenseVector(const DenseVector<T> &rhs) {}

VectorView<DenseVector<T> >
operator()(int from, int to)
{ return VectorView<DenseVector<T> >(); }
};

int fun(const DenseVector<double> &x) { return 1; }

int main()
{
DenseVector<double> x, y;
DenseVector<double> &w = x(1,3); // (1)
DenseVector<double> z = x(1,3); // (2)
fun(x(1,3)); // (3)
return 0;
}
//--------------------------------------------------------------------

What we are not able to comprehend is what happens in the three marked
lines:
In (2) x(1,3) creates an object of type VectorView<...> and its member
r is actually copied into z.
In (1) and (3) no such copying takes place.
Perhaps someone could tell us in detail what's going on internally in
those lines. Does it have to to with the copy constructor optimization
allowed by the standard in 12.8(15).
And if yes why does e.g. gcc 4.0 treat the three cases differently?
The standard does not enforce this optimization. But can it be
guaranteed that in (1) and (3) there will be no copying and that there
will always be copying in (2)?

Thanks
Alex
 
Reply With Quote
 
 
 
 
Valentin Samko
Guest
Posts: n/a
 
      10-30-2005
Alexander Stippler wrote:
> int main()
> {
> DenseVector<double> x, y;
> DenseVector<double> &w = x(1,3); // (1)
> DenseVector<double> z = x(1,3); // (2)
> fun(x(1,3)); // (3)
> return 0;
> }
> //--------------------------------------------------------------------
>
> What we are not able to comprehend is what happens in the three marked
> lines:
> In (2) x(1,3) creates an object of type VectorView<...> and its member
> r is actually copied into z.
> In (1) and (3) no such copying takes place.


In (1) you explicitly ask the compiler not to copy anything. `w` is a reference.

In (2) the compiler is allowed to optimise away the copy. I guess g++ was confused by the
fact that the type you return is different from the type you copy to.

In (3) you pass the new object to "fun" by reference, so again you explicitly ask it not
to copy.

You would understand your own code better if you had a simple example without all these
templates which only obscure the real problem.

--

Valentin Samko - http://www.valentinsamko.com
 
Reply With Quote
 
 
 
 
Alexander Stippler
Guest
Posts: n/a
 
      10-30-2005
In <4364f239$0$11871$(E-Mail Removed) ws.net> Valentin
Samko wrote:
> Alexander Stippler wrote:
>> int main()
>> {
>> DenseVector<double> x, y;
>> DenseVector<double> &w = x(1,3); // (1)
>> DenseVector<double> z = x(1,3); // (2)
>> fun(x(1,3)); // (3)
>> return 0;
>> }
>> //--------------------------------------------------------------------
>>
>> What we are not able to comprehend is what happens in the three
>> marked lines: In (2) x(1,3) creates an object of type VectorView<...>
>> and its member r is actually copied into z. In (1) and (3) no such
>> copying takes place.

>
> In (1) you explicitly ask the compiler not to copy anything. `w` is a
> reference.
>
> In (2) the compiler is allowed to optimise away the copy. I guess g++
> was confused by the fact that the type you return is different from
> the type you copy to.
>
> In (3) you pass the new object to "fun" by reference, so again you
> explicitly ask it not to copy.
>


But in (2) I pass the object by reference too. No difference to (3)
with respect to this.

> You would understand your own code better if you had a simple example
> without all these templates which only obscure the real problem.
>


Template code has different behavior in several areas. So I do not
want to understand it for non-template code and then recognize that
template code behaves diffent. And the templates do not add complexity
here. And in one place in the code they are not superfluous, but
essential to realize the Barton-Nackman-Trick.

> --
>
> Valentin Samko - http://www.valentinsamko.com
>

 
Reply With Quote
 
Alexander Stippler
Guest
Posts: n/a
 
      10-30-2005
In <43653c2b$0$50353$(E-Mail Removed) ws.net> Valentin
Samko wrote:
> Alexander Stippler wrote:
>>>> DenseVector<double> x, y;
>>>> DenseVector<double> &w = x(1,3); // (1)
>>>> DenseVector<double> z = x(1,3); // (2)
>>>> fun(x(1,3)); // (3)

>
>>> In (2) the compiler is allowed to optimise away the copy. I guess
>>> g++ was confused by the fact that the type you return is different
>>> from the type you copy to.
>>>
>>> In (3) you pass the new object to "fun" by reference, so again you
>>> explicitly ask it not to copy.
>>>

>>
>> But in (2) I pass the object by reference too. No difference to (3)
>> with respect to this.

> I do not see any references in the (2) code path. What do you mean by
> "I pass the object by reference too"?
>


The signature of fun is void fun(const DenseVector<double> &x), so
the argument is a const &. And the copy constructor for (2) expects
a const & too. Where am I wrong?
 
Reply With Quote
 
Valentin Samko
Guest
Posts: n/a
 
      10-30-2005
Alexander Stippler wrote:
>>> DenseVector<double> x, y;
>>> DenseVector<double> &w = x(1,3); // (1)
>>> DenseVector<double> z = x(1,3); // (2)
>>> fun(x(1,3)); // (3)


>> In (2) the compiler is allowed to optimise away the copy. I guess g++
>> was confused by the fact that the type you return is different from
>> the type you copy to.
>>
>> In (3) you pass the new object to "fun" by reference, so again you
>> explicitly ask it not to copy.
>>

>
> But in (2) I pass the object by reference too. No difference to (3)
> with respect to this.

I do not see any references in the (2) code path. What do you mean by "I pass the object
by reference too"?

--

Valentin Samko - http://www.valentinsamko.com
 
Reply With Quote
 
Valentin Samko
Guest
Posts: n/a
 
      10-30-2005
Alexander Stippler wrote:
>>>>> DenseVector<double> x, y;
>>>>> DenseVector<double> &w = x(1,3); // (1)
>>>>> DenseVector<double> z = x(1,3); // (2)
>>>>> fun(x(1,3)); // (3)
>>>> In (2) the compiler is allowed to optimise away the copy. I guess
>>>> g++ was confused by the fact that the type you return is different
>>>> from the type you copy to.
>>>>
>>>> In (3) you pass the new object to "fun" by reference, so again you
>>>> explicitly ask it not to copy.
>>>>
>>> But in (2) I pass the object by reference too. No difference to (3)
>>> with respect to this.

>> I do not see any references in the (2) code path. What do you mean by
>> "I pass the object by reference too"?
>>

> The signature of fun is void fun(const DenseVector<double> &x), so
> the argument is a const &. And the copy constructor for (2) expects
> a const & too. Where am I wrong?


1. Yes, you have a reference in the copy constructor, I missed that.

2. operator() returns object by value, this leads to one temporary (which may be optimised
away, this depends on implementation of operator ()).

3. this has nothing to do with the function "fun" as it is not called in (2).

4. In addition to a possible temporary, you are creating a new object "z" which will
contain a copy of that temporary.

--

Valentin Samko - http://val.samko.info
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
template copy constructor vs normal copy constructor cinsk C++ 35 10-10-2010 11:14 PM
Are destructors ever optimized away? Jonathan Lee C++ 10 05-23-2009 10:50 AM
static members of template classes optimized away? Markus Henschel C++ 8 02-14-2006 02:32 PM
const debug variable optimized away if false? Markus Dehmann C++ 11 03-20-2005 10:22 PM
Adding empty copy constructor makes segfault go away? William Payne C++ 4 08-28-2004 06:09 AM



Advertisments