Bug 1974 – overloaded assignment operators work on non-lvalues

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
Other
OS
Other
Creation time
2008-04-05T12:55:29Z
Last change time
2019-10-24T11:36:18Z
Keywords
accepts-invalid
Assigned to
No Owner
Creator
FeepingCreature

Comments

Comment #0 by default_357-line — 2008-04-05T12:55:29Z
Code: module test; import std.stdio; struct Foo { int y; void opAddAssign(int z) { y += z; } } struct Bar { Foo fou; Foo test() { return fou; } } void main() { Bar x; x.fou.y = 0; x.test() += 1337; writefln(x.fou.y); } The problem is that opAddAssign can be called even though the Foo it's being called on is not an lvalue at all. I see two solutions: either make this an error, or try to invoke opIndexAssign to write the value back after the expression has been evaluated. The first is probably easier.
Comment #1 by razvan.nitu1305 — 2019-09-13T08:36:28Z
This is a bit problematic because there are 2 points of view on this: 1. From a high-level point of view, the bug report is valid, you are trying to assign to an rvalue (x.test() = x.test() + 1337) which should an error. 2. From a lowering point of view you are basically calling the member function of a temporary object (x.test.opAddAssign(1337)), which by the current rules is valid behavior. I guess that what could be implemented is something along the lines of: if the opAssign/op*Assign function is pure, then you can error/warn because the call has no effect, otherwise it is possible that the assign function has side effects so calling it is correct. Anyhow, maybe I am over-engineering this?
Comment #2 by razvan.nitu1305 — 2019-10-24T11:36:18Z