Re: Copy elision by spec

2013-11-05 Thread Lars T. Kyllingstad

On Monday, 4 November 2013 at 19:55:50 UTC, deadalnix wrote:


In D, structs are movable by spec. It means internal pointer 
and other stuff like that are incorrect by spec.


Structs are movable != returned structs are guaranteed to be 
moved.


Re: Copy elision by spec

2013-11-05 Thread Denis Shelomovskij

04.11.2013 11:02, Lars T. Kyllingstad пишет:

My question is therefore, is this by design?  Can I rely on this to work
in the future, and on all compilers?  If this is the case, it really
should be added to the spec.


This is Issue 10372 [1].

[1] https://d.puremagic.com/issues/show_bug.cgi?id=10372

--
Денис В. Шеломовский
Denis V. Shelomovskij


Re: Copy elision by spec

2013-11-05 Thread Lars T. Kyllingstad
On Tuesday, 5 November 2013 at 16:22:57 UTC, Denis Shelomovskij 
wrote:

This is Issue 10372 [1].

[1] https://d.puremagic.com/issues/show_bug.cgi?id=10372


Thanks!  I've added a comment to the bug report.


Re: Copy elision by spec

2013-11-04 Thread Jakob Ovrum
On Monday, 4 November 2013 at 07:02:26 UTC, Lars T. Kyllingstad 
wrote:
I was quite surprised to see that the following program 
compiles just fine with DMD:


struct S
{
@disable this(this);
int n;
}

S createS(int i)
{
S s;
s.n = i;
return s;
}

void main(string[] args)
{
auto foo = createS(1);
foo = createS(2);
}

I already knew that the compiler was allowed to elide copies on 
return from functions, but I thought this was an optimisation, 
and not part of the language proper.  I would have expected the 
compiler to complain that createS() can't return an S since S's 
postblit constructor is disabled.


My question is therefore, is this by design?  Can I rely on 
this to work in the future, and on all compilers?  If this is 
the case, it really should be added to the spec.  (Or maybe 
it's there already, but I couldn't find it.)


Lars


My understanding is that your example illustrates a *move*, not a 
*copy*. AFAICT, non-copyable structs would be next to useless if 
we couldn't move them.


Re: Copy elision by spec

2013-11-04 Thread Lars T. Kyllingstad

On Monday, 4 November 2013 at 09:42:53 UTC, Jakob Ovrum wrote:
On Monday, 4 November 2013 at 07:02:26 UTC, Lars T. Kyllingstad 
wrote:
I was quite surprised to see that the following program 
compiles just fine with DMD:


   struct S
   {
   @disable this(this);
   int n;
   }

   S createS(int i)
   {
   S s;
   s.n = i;
   return s;
   }

   void main(string[] args)
   {
   auto foo = createS(1);
   foo = createS(2);
   }

I already knew that the compiler was allowed to elide copies 
on return from functions, but I thought this was an 
optimisation, and not part of the language proper.  I would 
have expected the compiler to complain that createS() can't 
return an S since S's postblit constructor is disabled.


My question is therefore, is this by design?  Can I rely on 
this to work in the future, and on all compilers?  If this is 
the case, it really should be added to the spec.  (Or maybe 
it's there already, but I couldn't find it.)


Lars


My understanding is that your example illustrates a *move*, not 
a *copy*. AFAICT, non-copyable structs would be next to useless 
if we couldn't move them.


I know, and I agree.  The question is whether this is a move *by 
specification*, i.e. whether the language makes a guarantee that 
return values are always moved under certain circumstances.  If 
so, this should be mentioned in the spec, along with a detailed 
description of said circumstances.


I am using this feature in a program I'm working on right now.  
It would be a shame if this is a mere DMD artifact, as opposed to 
a language feature, because then I can't depend on it working in 
other compilers or in future DMD versions.  I really don't know 
any other way to solve my problem either, so I'm keeping my 
fingers crossed that this can become part of the official spec.  
For anyone interested, the actual use case is a no-arguments 
constructor for a non-copyable struct, emulated with static 
opCall():


  struct Foo
  {
  // Constructor
  static Foo opCall()
  {
  Foo f;
  // Initialize f.
  return f;
  }

  // Foo should not be copyable.
  @disable this(this);
  }

  // Construct a new Foo
  auto foo = Foo();


Re: Copy elision by spec

2013-11-04 Thread Kenji Hara
2013/11/4 Lars T. Kyllingstad pub...@kyllingen.net

 On Monday, 4 November 2013 at 09:42:53 UTC, Jakob Ovrum wrote:

 On Monday, 4 November 2013 at 07:02:26 UTC, Lars T. Kyllingstad wrote:

 I was quite surprised to see that the following program compiles just
 fine with DMD:

struct S
{
@disable this(this);
int n;
}

S createS(int i)
{
S s;
s.n = i;
return s;
}

void main(string[] args)
{
auto foo = createS(1);
foo = createS(2);
}

 I already knew that the compiler was allowed to elide copies on return
 from functions, but I thought this was an optimisation, and not part of the
 language proper.  I would have expected the compiler to complain that
 createS() can't return an S since S's postblit constructor is disabled.

 My question is therefore, is this by design?  Can I rely on this to work
 in the future, and on all compilers?  If this is the case, it really should
 be added to the spec.  (Or maybe it's there already, but I couldn't find
 it.)

 Lars


 My understanding is that your example illustrates a *move*, not a *copy*.
 AFAICT, non-copyable structs would be next to useless if we couldn't move
 them.


 I know, and I agree.  The question is whether this is a move *by
 specification*, i.e. whether the language makes a guarantee that return
 values are always moved under certain circumstances.  If so, this should be
 mentioned in the spec, along with a detailed description of said
 circumstances.

 I am using this feature in a program I'm working on right now.  It would
 be a shame if this is a mere DMD artifact, as opposed to a language
 feature, because then I can't depend on it working in other compilers or in
 future DMD versions.  I really don't know any other way to solve my problem
 either, so I'm keeping my fingers crossed that this can become part of the
 official spec.  For anyone interested, the actual use case is a
 no-arguments constructor for a non-copyable struct, emulated with static
 opCall():

   struct Foo
   {
   // Constructor
   static Foo opCall()
   {
   Foo f;
   // Initialize f.
   return f;
   }

   // Foo should not be copyable.
   @disable this(this);
   }

   // Construct a new Foo
   auto foo = Foo();


I think it should be properly mentioned in language spec. Otherwise, we
cannot keep std.typecons.scoped in standard library.

Kenji Hara


Re: Copy elision by spec

2013-11-04 Thread Lars T. Kyllingstad

On Monday, 4 November 2013 at 07:17:12 UTC, monarch_dodra wrote:

http://d.puremagic.com/issues/show_bug.cgi?id=11287

According to the conversation, NRVO is supposed to be part of 
the spec, and you should expect it to work.


I'm not an expert, but aren't there cases where NRVO can't be 
applied?  For example:


  S foo()
  {
 S s1;
 // Initialize s1
 S s2;
 // Initialize s2
 if (someCondition) return s1;
 else return s2;
  }

However, the return value can always be *moved*.


Re: Copy elision by spec

2013-11-04 Thread monarch_dodra

On Monday, 4 November 2013 at 11:41:04 UTC, Lars T. Kyllingstad
wrote:

On Monday, 4 November 2013 at 07:17:12 UTC, monarch_dodra wrote:

http://d.puremagic.com/issues/show_bug.cgi?id=11287

According to the conversation, NRVO is supposed to be part of 
the spec, and you should expect it to work.


I'm not an expert, but aren't there cases where NRVO can't be 
applied?  For example:


  S foo()
  {
 S s1;
 // Initialize s1
 S s2;
 // Initialize s2
 if (someCondition) return s1;
 else return s2;
  }

However, the return value can always be *moved*.


According to Andrei
(http://video.ch9.ms/sessions/gonat/2013/AndreiQuickCodeGn13.zip
slide 37), NRVO requires All paths return same local. If not,
assume an extra copy.

IMO assume means that the compiler *may* elide the copy, but
*that* would be an optimization. If all your paths return the
same named local, then NRVO should be guaranteed.

But I think the spec should formalize the behavior.


Re: Copy elision by spec

2013-11-04 Thread Ali Çehreli

On 11/04/2013 03:23 AM, Lars T. Kyllingstad wrote:

 On Monday, 4 November 2013 at 09:42:53 UTC, Jakob Ovrum wrote:

 My understanding is that your example illustrates a *move*, not a
 *copy*. AFAICT, non-copyable structs would be next to useless if we
 couldn't move them.

 I know, and I agree.  The question is whether this is a move *by
 specification*, i.e. whether the language makes a guarantee that return
 values are always moved under certain circumstances.  If so, this should
 be mentioned in the spec, along with a detailed description of said
 circumstances.

I thought so too. So, I prepared the talk Copy and Move Semantics in D 
where 'move' is described as a fundamental struct operation. I presented 
the talk at the presence of Walter, Andrei, and other D experts and 
nobody objected! :p (I hope not merely because they were being polite.)


  http://dconf.org/2013/talks/cehreli.html

Ali



Re: Copy elision by spec

2013-11-04 Thread deadalnix
On Monday, 4 November 2013 at 11:23:33 UTC, Lars T. Kyllingstad 
wrote:
I know, and I agree.  The question is whether this is a move 
*by specification*, i.e. whether the language makes a guarantee 
that return values are always moved under certain 
circumstances.  If so, this should be mentioned in the spec, 
along with a detailed description of said circumstances.




In D, structs are movable by spec. It means internal pointer and 
other stuff like that are incorrect by spec.


Copy elision by spec

2013-11-03 Thread Lars T. Kyllingstad
I was quite surprised to see that the following program compiles 
just fine with DMD:


struct S
{
@disable this(this);
int n;
}

S createS(int i)
{
S s;
s.n = i;
return s;
}

void main(string[] args)
{
auto foo = createS(1);
foo = createS(2);
}

I already knew that the compiler was allowed to elide copies on 
return from functions, but I thought this was an optimisation, 
and not part of the language proper.  I would have expected the 
compiler to complain that createS() can't return an S since S's 
postblit constructor is disabled.


My question is therefore, is this by design?  Can I rely on this 
to work in the future, and on all compilers?  If this is the 
case, it really should be added to the spec.  (Or maybe it's 
there already, but I couldn't find it.)


Lars


Re: Copy elision by spec

2013-11-03 Thread monarch_dodra
On Monday, 4 November 2013 at 07:02:26 UTC, Lars T. Kyllingstad 
wrote:
My question is therefore, is this by design?  Can I rely on 
this to work in the future, and on all compilers?  If this is 
the case, it really should be added to the spec.  (Or maybe 
it's there already, but I couldn't find it.)


Lars


Funny you should ask:
http://d.puremagic.com/issues/show_bug.cgi?id=11287

According to the conversation, NRVO is supposed to be part of the 
spec, and you should expect it to work.