digitalmars.D.bugs - [Issue 1596] New: op*Assign should return void
- d-bugmail puremagic.com Oct 19 2007
- Don Clugston <dac nospam.com.au> Oct 23 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1596 Summary: op*Assign should return void Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: andrei metalanguage.com D's assignment operators opAddAssign, opMulAssign etc. have taken part of C++'s behavior in the area. In order to behave similarly to a primitive type, a user-defined operator typically returns *this as an rvalue (in C++ they'd usually return an lvalue). There are a few problems with this approach: 1. Extra busywork done for no good reason. The code: a += b; translates to: typeof(a) __unused = void; a.opAddAssign(b, __unused); So there is one extra memcpy performed for no reason (the copy is done on the caller site, which has no idea whether the result of the operation will be used or not). This problem will be exacerbated when copy construction semantics will be introduced. 2. Extra work for the programmer, and relying on convention instead of language rules. Experience with C++ shows that user-defined implementations of assignment operators always return *this, and that there is absolutely no reason to return anything else. Fix: The rule belongs to the language. Require all op*Assign to return void. If a value is required on the caller side, pass the left-hand side of the operation. --
Oct 19 2007
d-bugmail puremagic.com wrote:http://d.puremagic.com/issues/show_bug.cgi?id=1596 Summary: op*Assign should return void Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: andrei metalanguage.com D's assignment operators opAddAssign, opMulAssign etc. have taken part of C++'s behavior in the area. In order to behave similarly to a primitive type, a user-defined operator typically returns *this as an rvalue (in C++ they'd usually return an lvalue). There are a few problems with this approach: 1. Extra busywork done for no good reason. The code: a += b; translates to: typeof(a) __unused = void; a.opAddAssign(b, __unused); So there is one extra memcpy performed for no reason (the copy is done on the caller site, which has no idea whether the result of the operation will be used or not). This problem will be exacerbated when copy construction semantics will be introduced. 2. Extra work for the programmer, and relying on convention instead of language rules. Experience with C++ shows that user-defined implementations of assignment operators always return *this, and that there is absolutely no reason to return anything else. Fix: The rule belongs to the language. Require all op*Assign to return void. If a value is required on the caller side, pass the left-hand side of the operation.
I think this is right. But it's worth mentioning that this would break some of my code, since I'm using the return type of opXXAssign() operations in expression templates. However, since D expression templates don't work for comparison operators (because opCmp() returns an int), changing this is likely to force us to a better expression template solution.
Oct 23 2007








Don Clugston <dac nospam.com.au>