Bug 15842 – struct is being copied when returned directly

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2016-03-28T13:18:31Z
Last change time
2018-06-12T17:39:51Z
Assigned to
No Owner
Creator
ag0aep6g

Comments

Comment #0 by ag0aep6g — 2016-03-28T13:18:31Z
This is spin-off from issue 15832. test.d: ---- import std.stdio; struct S { this(int dummy) {writeln(&this);} } S f() {return S(0);} void main() { S s = f(); writeln(&s); } ---- The two `writeln`s print different addresses, so the struct is apparently constructed in a different location and gets copied on return. Change `f` to this and they print the same address: ---- S f() {S s = S(0); return s;} ---- I don't know what the ABI says about this, so this behavior may be allowed by the spec, but it's weird how adding a temporary makes the copy go away.
Comment #1 by hsteoh — 2016-03-31T18:21:03Z
I'm pretty sure this behaviour is according to spec. Structs are supposed to behave like glorified ints, meaning they are value types and may be freely copied around and moved when passing between functions. This is one reason it's a bad idea to keep internal pointers to a struct, as the pointers will become invalid once the struct is moved. Returning a struct from a function is generally implemented as storing in a temporary area on the stack, and moving to the final stack variable once control returns to the caller.
Comment #2 by hsteoh — 2016-03-31T18:23:24Z
(Small structs may also be returned via registers alone, but I surmise that using & on the struct will suppress this.)
Comment #3 by razvan.nitu1305 — 2018-06-12T16:49:10Z
Running both examples in the original bug report on master git HEAD results in printing the same address. Closing as fixed.
Comment #4 by atila.neves — 2018-06-12T17:06:50Z
I'd only close the bug if there's a test in the testsuite that would fail if the current behaviour ever changes.
Comment #5 by schveiguy — 2018-06-12T17:39:51Z
What is there to test? Either way is valid -- you can have the struct constructed in one location, and then moved to the return value, or you can have it constructed in place for the return value. There is no postblit or dtor, so the struct is movable without any notification. IMO, this should be resolved INVALID.