public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Guaranteed copy elision
@ 2022-11-15  5:47 Yubin Ruan
  2022-11-18 15:05 ` Stefan Ring
  2022-11-19 10:12 ` Jonathan Wakely
  0 siblings, 2 replies; 8+ messages in thread
From: Yubin Ruan @ 2022-11-15  5:47 UTC (permalink / raw)
  To: gcc-help

[-- Attachment #1: Type: text/plain, Size: 1247 bytes --]

Hi,

As mentioned in cppreference:
https://en.cppreference.com/w/cpp/language/copy_elision

it is guaranteed in c++17 that copy elision must be applied for some cases
like

    SomeBigObject SomeBigObject::Factory(...) {
        SomeBigObject local;
         ...
         return local;
    }

(examples taken from https://abseil.io/tips/11 )

but not for cases like

    SomeBigObject SomeBigObject::Factory(...) {
        SomeBigObject local1;
        SomeBigObject local2;
         ...

         if (cond_1) {
             return local1;
         } else {
             return local2;
         }
    }

For a c++ user, it is somewhat difficult to be 100% sure that copy elision
/ NVO is applied to the functions' return value above.

To be sure that a object would not be copied, we usually write something
like

         SomeBigObject obj;
         func(&obj);

while in most of the cases a one-liner like

         SomeBigObject obj = func();

would suffice.

Is there any language facility to help us guarantee that at compile time
(such as some kind of static_assert() ) so that we can be confident writing
those one-liner ?

I know that marking the copy constructor deleted would do the good, but
copy is needed in some cases.

Thanks
Yubin

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

* Re: Guaranteed copy elision
  2022-11-15  5:47 Guaranteed copy elision Yubin Ruan
@ 2022-11-18 15:05 ` Stefan Ring
  2022-11-18 21:35   ` Martin Oberzalek
  2022-11-19 10:12 ` Jonathan Wakely
  1 sibling, 1 reply; 8+ messages in thread
From: Stefan Ring @ 2022-11-18 15:05 UTC (permalink / raw)
  To: gcc-help

On Tue, Nov 15, 2022 at 6:48 AM Yubin Ruan via Gcc-help
<gcc-help@gcc.gnu.org> wrote:
>
> To be sure that a object would not be copied, we usually write something
> like
>
>          SomeBigObject obj;
>          func(&obj);
>
> while in most of the cases a one-liner like
>
>          SomeBigObject obj = func();
>
> would suffice.
>
> Is there any language facility to help us guarantee that at compile time
> (such as some kind of static_assert() ) so that we can be confident writing
> those one-liner ?

Interesting question, but unfortunately I do not have a good answer! I
can only bump the thread. ;)

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

* Re: Guaranteed copy elision
  2022-11-18 15:05 ` Stefan Ring
@ 2022-11-18 21:35   ` Martin Oberzalek
  2022-11-18 21:58     ` Segher Boessenkool
  0 siblings, 1 reply; 8+ messages in thread
From: Martin Oberzalek @ 2022-11-18 21:35 UTC (permalink / raw)
  To: gcc-help

Am Freitag, dem 18.11.2022 um 16:05 +0100 schrieb Stefan Ring via Gcc-
help:
> On Tue, Nov 15, 2022 at 6:48 AM Yubin Ruan via Gcc-help
> <gcc-help@gcc.gnu.org> wrote:
> > 
> > To be sure that a object would not be copied, we usually write
> > something
> > like
> > 
> >          SomeBigObject obj;
> >          func(&obj);
> > 
> > while in most of the cases a one-liner like
> > 
> >          SomeBigObject obj = func();
> > 
> > would suffice.
> > 
> > Is there any language facility to help us guarantee that at compile
> > time
> > (such as some kind of static_assert() ) so that we can be confident
> > writing
> > those one-liner ?
> 
> Interesting question, but unfortunately I do not have a good answer!
> I
> can only bump the thread. ;)

With c++ language features this may is a solution:


#include <iostream>
#include <vector>

class DoNotCopy
{

  std::vector<std::string> myData;
  
public:
  DoNotCopy( const DoNotCopy & other ) = delete;
  DoNotCopy & operator=( const DoNotCopy & other ) = delete;

  // valid move semantic
  // data within the vector will be moved, not copied
  DoNotCopy( const DoNotCopy && other )
    : myData( other.myData )
  {}

  DoNotCopy()
    : myData()
  {
  }
  
};


DoNotCopy func()
{
  DoNotCopy dnc;

  return dnc;
}

int main()
{
  DoNotCopy dnc = func(); // works

  DoNotCopy dnc2 = dnc; // error

  DoNotCopy dnc3;
  dnc3 = dnc; // error
}


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

* Re: Guaranteed copy elision
  2022-11-18 21:35   ` Martin Oberzalek
@ 2022-11-18 21:58     ` Segher Boessenkool
  2022-11-19 10:07       ` Jonathan Wakely
  0 siblings, 1 reply; 8+ messages in thread
From: Segher Boessenkool @ 2022-11-18 21:58 UTC (permalink / raw)
  To: Martin Oberzalek; +Cc: gcc-help

On Fri, Nov 18, 2022 at 10:35:20PM +0100, Martin Oberzalek via Gcc-help wrote:
> Am Freitag, dem 18.11.2022 um 16:05 +0100 schrieb Stefan Ring via Gcc-
> help:
> > On Tue, Nov 15, 2022 at 6:48 AM Yubin Ruan via Gcc-help
> > <gcc-help@gcc.gnu.org> wrote:
> > > Is there any language facility to help us guarantee that at compile
> > > time
> > > (such as some kind of static_assert() ) so that we can be confident
> > > writing
> > > those one-liner ?

> With c++ language features this may is a solution:

Nope.  Try with -O0 for example.

There is no way to guarantee copy elision.  It isn't even clear what
*exactly* you want guaranteed, what "copy elision" means *exactly*, what
"guaranteeing copy elision" means, etc.

If you write clear and simple (which means: not artificially made
complex) and correct source code, you can trust the compiler will
generate good machine code for you (if you use -O2 or such).  If not,
bug reports are welcome!

A C compiler is not a "portable assembler", you have no direct control
over generated code.  This is a good thing: the compiler is much better
at writing fast machine code than users are.


Segher

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

* Re: Guaranteed copy elision
  2022-11-18 21:58     ` Segher Boessenkool
@ 2022-11-19 10:07       ` Jonathan Wakely
  0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Wakely @ 2022-11-19 10:07 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Martin Oberzalek, gcc-help

[-- Attachment #1: Type: text/plain, Size: 1747 bytes --]

On Fri, 18 Nov 2022, 22:00 Segher Boessenkool, <segher@kernel.crashing.org>
wrote:

> On Fri, Nov 18, 2022 at 10:35:20PM +0100, Martin Oberzalek via Gcc-help
> wrote:
> > Am Freitag, dem 18.11.2022 um 16:05 +0100 schrieb Stefan Ring via Gcc-
> > help:
> > > On Tue, Nov 15, 2022 at 6:48 AM Yubin Ruan via Gcc-help
> > > <gcc-help@gcc.gnu.org> wrote:
> > > > Is there any language facility to help us guarantee that at compile
> > > > time
> > > > (such as some kind of static_assert() ) so that we can be confident
> > > > writing
> > > > those one-liner ?
>
> > With c++ language features this may is a solution:
>
> Nope.  Try with -O0 for example.
>
> There is no way to guarantee copy elision.  It isn't even clear what
> *exactly* you want guaranteed, what "copy elision" means *exactly*, what
> "guaranteeing copy elision" means, etc.
>

The standard defines what it means here:
https://eel.is/c++draft/class.copy.elision

Since C++17 it is guaranteed in certain situations:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html

There is a proposal to guarantee it in more cases, including the one the OP
asked about:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2025r2.html
That has not been approved for the standard, but it explains the status quo
quite well.


> If you write clear and simple (which means: not artificially made
> complex) and correct source code, you can trust the compiler will
> generate good machine code for you (if you use -O2 or such).  If not,
> bug reports are welcome!
>
> A C compiler is not a "portable assembler", you have no direct control
> over generated code.  This is a good thing: the compiler is much better
> at writing fast machine code than users are.
>
>
> Segher
>

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

* Re: Guaranteed copy elision
  2022-11-15  5:47 Guaranteed copy elision Yubin Ruan
  2022-11-18 15:05 ` Stefan Ring
@ 2022-11-19 10:12 ` Jonathan Wakely
  2022-11-21 14:17   ` Yubin Ruan
  1 sibling, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2022-11-19 10:12 UTC (permalink / raw)
  To: Yubin Ruan; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 1799 bytes --]

On Tue, 15 Nov 2022, 05:48 Yubin Ruan via Gcc-help, <gcc-help@gcc.gnu.org>
wrote:

> Hi,
>
> As mentioned in cppreference:
> https://en.cppreference.com/w/cpp/language/copy_elision
>
> it is guaranteed in c++17 that copy elision must be applied for some cases
> like
>
>     SomeBigObject SomeBigObject::Factory(...) {
>         SomeBigObject local;
>          ...
>          return local;
>     }
>

No, this is not guaranteed. As the cppreference page explains, it's only
guaranteed for copying temporaries. This is not a temporary.

Elision here is allowed, but not required. It's commonly implemented though.




> (examples taken from https://abseil.io/tips/11 )
>
> but not for cases like
>
>     SomeBigObject SomeBigObject::Factory(...) {
>         SomeBigObject local1;
>         SomeBigObject local2;
>          ...
>
>          if (cond_1) {
>              return local1;
>          } else {
>              return local2;
>          }
>     }
>
> For a c++ user, it is somewhat difficult to be 100% sure that copy elision
> / NVO is applied to the functions' return value above.
>
> To be sure that a object would not be copied, we usually write something
> like
>
>          SomeBigObject obj;
>          func(&obj);
>
> while in most of the cases a one-liner like
>
>          SomeBigObject obj = func();
>
> would suffice.
>
> Is there any language facility to help us guarantee that at compile time
> (such as some kind of static_assert() ) so that we can be confident writing
> those one-liner ?
>

Make it cheap to move, and then it will be moved instead of copied. The
move isn't always elided, but if it's cheap then the code will still be
efficient.


> I know that marking the copy constructor deleted would do the good, but
> copy is needed in some cases.
>
> Thanks
> Yubin
>

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

* Re: Guaranteed copy elision
  2022-11-19 10:12 ` Jonathan Wakely
@ 2022-11-21 14:17   ` Yubin Ruan
  2022-11-21 14:20     ` Jonathan Wakely
  0 siblings, 1 reply; 8+ messages in thread
From: Yubin Ruan @ 2022-11-21 14:17 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 1947 bytes --]

On Sat, Nov 19, 2022 at 6:12 PM Jonathan Wakely <jwakely.gcc@gmail.com>
wrote:

>
>
> On Tue, 15 Nov 2022, 05:48 Yubin Ruan via Gcc-help, <gcc-help@gcc.gnu.org>
> wrote:
>
>> Hi,
>>
>> As mentioned in cppreference:
>> https://en.cppreference.com/w/cpp/language/copy_elision
>>
>> it is guaranteed in c++17 that copy elision must be applied for some cases
>> like
>>
>>     SomeBigObject SomeBigObject::Factory(...) {
>>         SomeBigObject local;
>>          ...
>>          return local;
>>     }
>>
>
> No, this is not guaranteed. As the cppreference page explains, it's only
> guaranteed for copying temporaries. This is not a temporary.
>
> Elision here is allowed, but not required. It's commonly implemented
> though.
>
>
>
>
>> (examples taken from https://abseil.io/tips/11 )
>>
>> but not for cases like
>>
>>     SomeBigObject SomeBigObject::Factory(...) {
>>         SomeBigObject local1;
>>         SomeBigObject local2;
>>          ...
>>
>>          if (cond_1) {
>>              return local1;
>>          } else {
>>              return local2;
>>          }
>>     }
>>
>> For a c++ user, it is somewhat difficult to be 100% sure that copy elision
>> / NVO is applied to the functions' return value above.
>>
>> To be sure that a object would not be copied, we usually write something
>> like
>>
>>          SomeBigObject obj;
>>          func(&obj);
>>
>> while in most of the cases a one-liner like
>>
>>          SomeBigObject obj = func();
>>
>> would suffice.
>>
>> Is there any language facility to help us guarantee that at compile time
>> (such as some kind of static_assert() ) so that we can be confident
>> writing
>> those one-liner ?
>>
>
> Make it cheap to move, and then it will be moved instead of copied. The
> move isn't always elided, but if it's cheap then the code will still be
> efficient.
>

Thank you all.

It seems that currently the only way to guarantee  efficiency is to use
move instead.

--
Yubin

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

* Re: Guaranteed copy elision
  2022-11-21 14:17   ` Yubin Ruan
@ 2022-11-21 14:20     ` Jonathan Wakely
  0 siblings, 0 replies; 8+ messages in thread
From: Jonathan Wakely @ 2022-11-21 14:20 UTC (permalink / raw)
  To: Yubin Ruan; +Cc: gcc-help

On Mon, 21 Nov 2022 at 14:17, Yubin Ruan wrote:
> It seems that currently the only way to guarantee  efficiency is to use move instead.

The move will happen automatically. All you need to do is have an
efficient move constructor, the compiler does the rest.

You do not need to say 'return std::move(local1);' because that
happens automatically.

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

end of thread, other threads:[~2022-11-21 14:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-15  5:47 Guaranteed copy elision Yubin Ruan
2022-11-18 15:05 ` Stefan Ring
2022-11-18 21:35   ` Martin Oberzalek
2022-11-18 21:58     ` Segher Boessenkool
2022-11-19 10:07       ` Jonathan Wakely
2022-11-19 10:12 ` Jonathan Wakely
2022-11-21 14:17   ` Yubin Ruan
2022-11-21 14:20     ` Jonathan Wakely

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).