function not callable using struct constructor

Jonathan M Davis jmdavisProg at gmx.com
Fri Jan 3 02:19:33 PST 2014


On Friday, January 03, 2014 10:06:49 alex burton wrote:
> On Friday, 3 January 2014 at 03:59:50 UTC, Jonathan M Davis wrote:
> > On Friday, January 03, 2014 03:13:12 alex burton wrote:
> >> struct Foo
> >> {
> >> };
> >> 
> >> void bar(ref Foo f)
> >> {
> >> }
> >> 
> >> void main()
> >> {
> >> bar(Foo()); //Error: function test.bar (ref Foo f) is not
> >> callable using argument types (Foo)
> >> }
> >> 
> >> I get the above error with 2.064 not with 2.060.
> >> Is it a bug ?
> >> 
> >> Is it a feature ?
> >> If so :
> >> Why can't I take a non const ref to a temp struct - It might
> >> look
> >> a bit silly but I might be doing it to avoid copying.
> >> 
> >> I could still do this :
> >> 
> >> void main()
> >> {
> >> Foo f = Foo();
> >> bar(f);
> >> }
> >> 
> >> Which is equivalent AFAIK
> > 
> > ref parameters only accept lvalues. Foo() creates a temporary
> > and is not an
> > lvalue. If you want a function to accept rvalues, it has to not
> > take its
> > argument by ref. If you want to avoid copying lvalues and still
> > accept
> > rvalues, then you need to overload the function (one which
> > takes ref and one
> > which doesn't). And unlike in C++, constness has no effect on
> > whether ref
> > accepts rvalues. ref only ever accepts lvalues.
> > 
> > However, in the case of rvalues, ref doesn't save you anything
> > performance-
> > wise. No copy will occur. Rather, because it's an rvalue, it
> > can just move it
> > into the function's parameter rather than copying it. ref only
> > saves you
> > copying with lvalues.
> > 
> > - Jonathan M Davis
> 
> Thanks for this, although I tested in 2.064 and the above code
> works using void bar(in Foo f), which would seem to contracdict
> "constness has no effect on whether ref accepts rvalues" if I
> understand it correctly.

in on a paremeter is the same as const scope and has nothing to do with ref. 
And since scope currently only has any effect on delegates, your declaration is 
effectively identical to

void bar(const Foo f);

> After looking at the asm, it appears that the compiler doesn't
> copy the struct when using a void bar(Foo f), but also can avoid
> copying if a second function like bar is called from bar.
> 
> It appears that passing by value is what I need, and I should
> trust the compiler.

D was specifically designed so that the compiler could avoid copying structs as 
much as possible. In principle, if the compiler can do a move, it will (though 
it's quite likely that there are places where it doesn't yet do a move where 
it should, since the implementation isn't perfect).

http://stackoverflow.com/questions/6884996/questions-about-postblit-and-move-semantics

- Jonathan M Davis


More information about the Digitalmars-d mailing list