www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Bug with references (no casting used)

reply "andrea9940" <no mail.plz> writes:
Hi everyone,
I was trying to get my vector struct to use extensively 
references for passing parameters and I found a subtle bug which 
make me lose a few hour.

A sample code that shows the bug is here 
http://pastebin.com/rvcNdjAE (fails with dmd 2.064 on linux)
I think that the code is wrong and dmd does not recognize it:
opBinary() allocates a struct on the stack which is then accepted 
by reference in opOpAssign.

I'd like to know if currently there are correct ways to pass 
rvalue structs by reference or if I should pass everything by 
value and hope the compiler optimizes all reduntant copies.
Feb 22 2014
next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 22 February 2014 at 17:22:51 UTC, andrea9940 wrote:
 Hi everyone,
 I was trying to get my vector struct to use extensively 
 references for passing parameters and I found a subtle bug 
 which make me lose a few hour.

 A sample code that shows the bug is here 
 http://pastebin.com/rvcNdjAE (fails with dmd 2.064 on linux)
 I think that the code is wrong and dmd does not recognize it:
 opBinary() allocates a struct on the stack which is then 
 accepted by reference in opOpAssign.

 I'd like to know if currently there are correct ways to pass 
 rvalue structs by reference or if I should pass everything by 
 value and hope the compiler optimizes all reduntant copies.
Looks like compiler bug.
Feb 22 2014
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
On Saturday, 22 February 2014 at 17:22:51 UTC, andrea9940 wrote:
 Hi everyone,
 I was trying to get my vector struct to use extensively 
 references for passing parameters and I found a subtle bug 
 which make me lose a few hour.

 A sample code that shows the bug is here 
 http://pastebin.com/rvcNdjAE (fails with dmd 2.064 on linux)
 I think that the code is wrong and dmd does not recognize it:
 opBinary() allocates a struct on the stack which is then 
 accepted by reference in opOpAssign.
Clarifying: The bug is that opBinary returns a reference to a local (vector), which is invalid. I don't know if dmd should see that, as it's hidden behind a call.
 I'd like to know if currently there are correct ways to pass 
 rvalue structs by reference or if I should pass everything by 
 value and hope the compiler optimizes all reduntant copies.
There isn't. But adding an overload that forwards to the ref version is trivial (as long as there's only one parameter): --- auto opOpAssign(string op)(const Vector rhs) if (op == "+" || op == "-") { return opOpAssign!op(rhs); } --- I don't know if the ref even buys you anything performance-wise, though.
Feb 22 2014
prev sibling parent Artur Skawina <art.08.09 gmail.com> writes:
On 02/22/14 18:22, andrea9940 wrote:
 I was trying to get my vector struct to use extensively references for passing
parameters and I found a subtle bug which make me lose a few hour.
 
 A sample code that shows the bug is here http://pastebin.com/rvcNdjAE (fails
with dmd 2.064 on linux)
 I think that the code is wrong and dmd does not recognize it:
 opBinary() allocates a struct on the stack which is then accepted by reference
in opOpAssign.
That is ok; the problem is that opBinary returns a local stack-allocated object by reference. Make it return by value, and with some help from RVO you should get only one copy (which is necessary because you create a new Vector instance). IOW: Vector opBinary(string op)(T rhs) const; ref Vector opOpAssign(string op)(T rhs); ref Vector opOpAssign(string op)(auto ref const Vector rhs); artur
Feb 22 2014