Temporary objects

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

Temporary objects

by DE-11 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

hi all

unfortunately i'm totally out of time now
so i only write my proposal and an example
forgive me for that

the code

    #include <algorithm>
    template<typename type>
    class temporary : public type
    {
      temporary() : type() {}
      temporary(temporary &a) : type()
      {
        using std::swap;
        swap(static_cast<type&>(*this), static_cast<type&>(a));
      }
      template<typename other>
      temporary(const other &a) : type(a) {}
      temporary &operator=(temporary &a)
      {
        using std::swap;
        swap(static_cast<type&>(*this), static_cast<type&>(a));
        return *this;
      }
      template<typename other>
      temporary &operator=(const other &a)
      { type::operator=(a); return *this; }
    };

example1

    temporary<huge_type> foo(const huge_type &a)
    {//returning temporary object
      temporary<huge_type> ret;  //or even 'ret(a)'
      //doing something...
      return ret;
    }
    //...
    huge_type result;
    result = foo(bar);  //somewhere in code

only one copy operation -- assignment operator
return by value copying overhead is eliminated with help of swap()

example2

    struct my_type
    {
      //...
      my_type(temporary<my_type> &a) { this->swap(a); }
      //...
      my_type &operator=(temporary<my_type> &a)
      { this->swap(a); return *this; }
      //...
    };

    temporary<my_type> process(const my_type &item)
    {
      temporary<my_type> ret;
      //processing item...
      return ret;
    }
    //...
    my_type result = process(item);  //somewhere in code
    //or
    result = process(item);

no temporary object handling overhead at all
return by value, copy-construct and assign from temporary objects for
free!

thank you for attention
   

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Joel.Falcou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

DE wrote:
> hi all
>
> unfortunately i'm totally out of time now
> so i only write my proposal and an example
> forgive me for that
>  
What about a good read on Named Return Value Optimization and the
upcoming move features ...

--
___________________________________________
Joel Falcou - Assistant Professor
PARALL Team - LRI - Universite Paris Sud XI
Tel : (+33)1 69 15 66 35


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Dmitry Goncharov-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



> no temporary object handling overhead at all
> return by value, copy-construct and assign from temporary objects for
> free!
>
>  
Only for the types which can be swapped efficiently

BR, Dmitry
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Thomas Klimpel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

DE wrote:
> unfortunately i'm totally out of time now
> so i only write my proposal and an example
> forgive me for that

Now you will have to forgive us our cryptic answers. And I assume that you are somewhat familiar with copy elision, return value optimization, rvalues and some move-emulation libraries and move-support proposals (rvalue references).


>     template<typename type>
>     class temporary : public type

This is actually an interesting semantic. I just checked and found that the proposed Boost.Move library also uses the same semantics (move.hpp:72-73:
template <class T>
class rv : public T
), but the older Adobe Move library doesn't use it, and the semantics of the proposed rvalue-reference is also different from this.

What I like about this semantics is that for

class A {...};
class B : public A {...};

the type "temporary<B>&" cannot implicitly be converted to "temporary<A>&". For the proposed rvalue-reference, the type "B&&" can implicitly be converted to "A&&", and I have the impression that this can lead to behavior even worse than slicing.


Regards,
Thomas
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by DE-11 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

on 30.10.2009 at 1:02
 joel wrote :
> What about a good read on Named Return Value Optimization and the
> upcoming move features ...
afaik nrvo is not implemented in msvc80
certainly it would be nice to have such but with current standard it
is very hard to implement it because it is very hard to statically
analyse the code of copy constructor and assignment operator
i mean either the standard would be broken or the optimized code might
produce unexpected behavior, e.g. where you expect 2 copy constructors
there is only 1 etc.

i live in real world (i.e. with c++98 standard) and propose very simple
yet efficient and complete (in several scope) solution
while nrvo is not guaranteed (again afaik) to take place this approach
will always (!) work if it is explicitly stated so

i'm not familiar with upcoming move features but my guess is that it
will be some nerdy metaprogramming (no offence guys) while i propose
almost trivial solution which can be started using right now without
even changing classes (structs) definitions

--
Pavel

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by DE-11 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

on 30.10.2009 at 10:38
 Dmitry Goncharov wrote :
> Only for the types which can be swapped efficiently
of course
but there are plenty of such

--
Pavel

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by DE-11 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

on 30.10.2009 at 12:57
 Thomas Klimpel wrote :
>>     template<typename type>
>>     class temporary : public type
> This is actually an interesting semantic. I just checked and found
> that the proposed Boost.Move library also uses the same semantics (move.hpp:72-73:
> template <class T>
> class rv : public T
> ), but the older Adobe Move library doesn't use it, and the
> semantics of the proposed rvalue-reference is also different from this.

> What I like about this semantics is that for

> class A {...};
> class B : public A {...};

> the type "temporary<B>&" cannot implicitly be converted to
> "temporary<A>&". For the proposed rvalue-reference, the type "B&&"
> can implicitly be converted to "A&&", and I have the impression that
> this can lead to behavior even worse than slicing.
very good point
i didn't think about it

well, i'd try to rephrase this issue:
for D derived from B does swap(A, B) implements the right semantics
and what is that "right semantics"?
but this looks like off topic so far

--
Pavel

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Joel.Falcou :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

DE wrote:
> some unbacked claims ...
>  
Read and learn

http://cpp-next.com/archive/category/value-semantics/

--
___________________________________________
Joel Falcou - Assistant Professor
PARALL Team - LRI - Universite Paris Sud XI
Tel : (+33)1 69 15 66 35


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by DE-11 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

on 30.10.2009 at 12:57
 Thomas Klimpel wrote :
> For the proposed rvalue-reference, the type "B&&"
> can implicitly be converted to "A&&", and I have the impression that
> this can lead to behavior even worse than slicing.
by the way such reasoning can really put that proposal on ice and
we'll not see it in the new standard

on the other hand all responsibility can be laid on users' shoulders

--
Pavel

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Thomas Klimpel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

DE wrote:
> by the way such reasoning can really put that proposal on ice and
> we'll not see it in the new standard
>
> on the other hand all responsibility can be laid on users' shoulders

Well, since swap itself has the same issues, there's no reason to put the proposal on ice.

The point of the rvalue-references proposal is probably that rvalue-references are like normal references with slightly different rules which objects they can bind. This is easy for a compiler to implement and easy for a user to understand.


What I really would like for the move-proposal is to allow implementing the move-assignment operator as a simple swap, even for vector or shared_ptr. However, it won't happen. First of all, convincing everybody that it makes sense is impossible, and on top of that another language change would be required. The language change would have to say that temporary objects that bind to a non-const rvalue-reference get destroyed directly after the function/method returns (in order to avoid a counter-example that Dave proposed). This change would be difficult to implement for a compiler and difficult for a user to understand.


I guess what will happen is that most major compilers will implement rvalue-references long before they make it officially into the standard (since the standard will be ready soon, this implies that most major compilers have already implemented rvalue-references) and that the standard libraries will implement and exploit move-support at the same time. And when the next standard will be finished, it will contain rvalue-references and move-support, and it will be good enough for all practical purposes. And Scott Meyers will either have to explain how to implement a "well behaved" move-assignment operator, or explain that one has to be careful when using std::move or std::move_iterator. I guess he will have to explain both anyway :-)

I just hope that there will be some agreement on what is considered to be a "well behaved" move-assignment operator.


Regards,
Thomas
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Mathias Gaunard-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

DE wrote:

> afaik nrvo is not implemented in msvc80

RVO is implemented since MSVC6, NRVO since MSVC7.


> certainly it would be nice to have such but with current standard it
> is very hard to implement

Not really. You just have to deduce the expression you're returning is
either a temporary or a local variable, which is hardly difficult for a
compiler.


> it because it is very hard to statically
> analyse the code of copy constructor and assignment operator

NRVO doesn't involve the assignment operator at all.
The optimization also doesn't even require to know what the definition
of the copy constructor is, so static analysis of its definition is
irrelevant.


> i mean either the standard would be broken or the optimized code might
> produce unexpected behavior, e.g. where you expect 2 copy constructors
> there is only 1 etc.

The standard explicitly states that the compiler is allowed to elide
calls to the copy constructor in certain situations, even if the copy
constructor in question has side effects.
It also states the same thing for move constructors in C++0x.


> while nrvo is not guaranteed (again afaik) to take place this approach
> will always (!) work if it is explicitly stated so

Boost.Move already provides move emulation for C++03, and moving is
independent from NRVO.


> i'm not familiar with upcoming move features but my guess is that it
> will be some nerdy metaprogramming (no offence guys) while i propose
> almost trivial solution which can be started using right now without
> even changing classes (structs) definitions

Boost.Move is actually fairly similar to what you are proposing.

And no, it's not nerdy meta-programming, C++0x is simply introducing a
new mechanism to distinguish rvalues from lvalues: rvalue references.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Mathias Gaunard-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Klimpel wrote:

> What I really would like for the move-proposal is to allow implementing the move-assignment operator as a simple swap

Testing shows that this is suboptimal and can hurt performance
significantly.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Thomas Klimpel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Mathias Gaunard wrote:
> Thomas Klimpel wrote:
> > What I really would like for the move-proposal is to allow implementing the move-assignment operator as a simple swap
>
> Testing shows that this is suboptimal and can hurt performance
> significantly.

You probably want to say that implementing "a = std::move(b)" as

tmp.members = a.members
a.members = b.members
b.members = tmp.members

is significantly slower than implementing it as

a.members = b.members

I believe this without testing. What I'm talking about is that the move-assignment operator of the proposed boost::container::vector is implemented for good reasons as

   vector& operator=(BOOST_RV_REF(vector) x)
   {
      if (&x != this){
         this->swap(x);
         x.clear();
      }
      return *this;
   }

and it would be nice if it would be allowed to implement it as


   vector& operator=(BOOST_RV_REF(vector) x)
   {
      this->swap(x);
      return *this;
   }


However, I accepted that "it would be nice" won't come reality, because the good reasons are just too good (with the otherwise required language change as final word).


Regards,
Thomas
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Sebastian Redl :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Klimpel wrote:
> I guess what will happen is that most major compilers will implement rvalue-references long before they make it officially into the standard (since the standard will be ready soon, this implies that most major compilers have already implemented rvalue-references)
There's no need to guess. GCC, CodeGear C++Builder, MSVC++, Comeau and
Clang all have implemented rvalue references already, although in some
cases with early draft semantics.

Sebastian
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by DE-11 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

on 31.10.2009 at 17:12
 Mathias Gaunard wrote :
>> afaik nrvo is not implemented in msvc80
> RVO is implemented since MSVC6, NRVO since MSVC7.
you might know better
however afaik these are of very limited use

>> certainly it would be nice to have such but with current standard it
>> is very hard to implement
> Not really. You just have to deduce the expression you're returning is
> either a temporary or a local variable, which is hardly difficult for a
> compiler.
>> it because it is very hard to statically
>> analyse the code of copy constructor and assignment operator
> NRVO doesn't involve the assignment operator at all.
> The optimization also doesn't even require to know what the definition
> of the copy constructor is, so static analysis of its definition is
> irrelevant.
i mean that in an example like

    type foo(const type &to_be_processed)
    {
      type ret;
      //processing
      return ret;
    }

semantics of the copy constructor does matter
here nrvo likely not to take place (actually it should NOT take place)

>> i mean either the standard would be broken or the optimized code might
>> produce unexpected behavior, e.g. where you expect 2 copy constructors
>> there is only 1 etc.
> The standard explicitly states that the compiler is allowed to elide
> calls to the copy constructor in certain situations, even if the copy
> constructor in question has side effects.
> It also states the same thing for move constructors in C++0x.
afaik by the standard a compiler only allowed to directly construct a
temporary only in case like

    type bar(const other &a)
    {
      intermediate i;
      //???
      return type(i);
    }
    //...
    res = bar(input);
   

>> while nrvo is not guaranteed (again afaik) to take place this approach
>> will always (!) work if it is explicitly stated so
> Boost.Move already provides move emulation for C++03, and moving is
> independent from NRVO.
>> i'm not familiar with upcoming move features but my guess is that it
>> will be some nerdy metaprogramming (no offence guys) while i propose
>> almost trivial solution which can be started using right now without
>> even changing classes (structs) definitions
> Boost.Move is actually fairly similar to what you are proposing.
well, to this point i still think that a temporary<type> better
reflects the underlying semantics than, i guess, BOOST_RV_REF(type) (looks extremely ugly)

> And no, it's not nerdy meta-programming, C++0x is simply introducing a
> new mechanism to distinguish rvalues from lvalues: rvalue references.
i have a picture of that and you can't imagine how hard i wait for
the new standard
but for now i try to exploit existing tools
that's why all these perversions exist

--
Pavel

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by DE-11 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

on 31.10.2009 at 18:37
 Thomas Klimpel wrote :
> What I'm talking about is that the
> move-assignment operator of the proposed boost::container::vector is implemented for good reasons as

>    vector& operator=(BOOST_RV_REF(vector) x)
>    {
>       if (&x != this){
>          this->swap(x);
>          x.clear();
>       }
>       return *this;
>    }

> and it would be nice if it would be allowed to implement it as


>    vector& operator=(BOOST_RV_REF(vector) x)
>    {
>       this->swap(x);
>       return *this;
>    }


> However, I accepted that "it would be nice" won't come reality,
> because the good reasons are just too good (with the otherwise
> required language change as final word).
good point, i second this
i think there is no need for self-assignment test
rather assignment (or whatever) should be implemented in a
self-assignment-safe manner
also there is no need to 'clear()' because the destructor will take care
of whatever the object 'x' remains to be
and finally i think that 'this->swap(x)' and 'x.swap(*this)' must have
identical by definition effect so there is no matter what form to use

--
Pavel

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Steven Watanabe-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

AMDG

DE wrote:

> on 31.10.2009 at 17:12
>  Mathias Gaunard wrote :
>  
>> NRVO doesn't involve the assignment operator at all.
>> The optimization also doesn't even require to know what the definition
>> of the copy constructor is, so static analysis of its definition is
>> irrelevant.
>>    
> i mean that in an example like
>
>     type foo(const type &to_be_processed)
>     {
>       type ret;
>       //processing
>       return ret;
>     }
>
> semantics of the copy constructor does matter
> here nrvo likely not to take place (actually it should NOT take place)
>  

This is exactly the case where NRVO should happen.
(NRVO stands for named return value optimization as
opposed to RVO which is for temporaries)

In Christ,
Steven Watanabe

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Thomas Klimpel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

DE wrote:
> Mathias Gaunard wrote:
> > Boost.Move is actually fairly similar to what you are proposing.
> well, to this point i still think that a temporary<type> better
> reflects the underlying semantics than, i guess, BOOST_RV_REF(type) (looks extremely ugly)

Boost.Move is really similar to what you are proposing, but it also handles the case that the compiler actually supports rvalue-references. So BOOST_RV_REF is a macro defined as:

#ifdef BOOST_HAS_RVALUE_REFS
  #define BOOST_RV_REF(TYPE) TYPE &&
#else
  #define BOOST_RV_REF(TYPE) boost::rv< TYPE >&
#endif

It is true that macros always look ugly, but this is exactly the situation where you have to use a macro to abstract away unavoidable language differences.

Regards,
Thomas
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by Mathias Gaunard-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

DE wrote
> on 31.10.2009 at 17:12
>  Mathias Gaunard wrote :
>>> afaik nrvo is not implemented in msvc80
>> RVO is implemented since MSVC6, NRVO since MSVC7.
> you might know better
> however afaik these are of very limited use

They do what the name says.


> i mean that in an example like
>
>     type foo(const type &to_be_processed)
>     {
>       type ret;
>       //processing
>       return ret;
>     }
>
> semantics of the copy constructor does matter

No, they don't.


> here nrvo likely not to take place (actually it should NOT take place)

That's exactly the case where it will.


> afaik by the standard a compiler only allowed to directly construct a
> temporary only in case like
>
>     type bar(const other &a)
>     {
>       intermediate i;
>       //???
>       return type(i);
>     }
>     //...
>     res = bar(input);

This is a bad example of RVO which doesn't actually work. There will
still be a temporary here.


> well, to this point i still think that a temporary<type> better
> reflects the underlying semantics than, i guess, BOOST_RV_REF(type) (looks extremely ugly)

The point of the macro is that it can use type&& (rvalue references) or
temporary<type> depending on what is available.


> i have a picture of that and you can't imagine how hard i wait for
> the new standard
> but for now i try to exploit existing tools
> that's why all these perversions exist

The right approach is to design systems that look that those of the
future, that can use the future features when available and that
fallback on emulation techniques when they're not.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Re: Temporary objects

by DE-11 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

on 02.11.2009 at 20:52
 Steven Watanabe wrote :

>> i mean that in an example like
>>
>>     type foo(const type &to_be_processed)
>>     {
>>       type ret;
>>       //processing
>>       return ret;
>>     }
>>
>> semantics of the copy constructor does matter
>> here nrvo likely not to take place (actually it should NOT take place)
>>  
> This is exactly the case where NRVO should happen.
> (NRVO stands for named return value optimization as
> opposed to RVO which is for temporaries)
well, then my question is: _will_ it happen?

--
Pavel

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
< Prev | 1 - 2 | Next >