The 'ref' by 'getA' is ignored.
[code]
import std.stdio;
struct A {
public:
int id;
this(int id) {
writeln("CTor ", id);
this.id = id;
}
this(this) {
writeln("Postblit ", this.id);
this.id *= 2;
}
~this() {
writeln("DTor ", this.id);
}
}
class B {
private:
A _a;
public:
this() {
this._a = A(42);
}
ref A getA() {
writeln("Return A");
return this._a;
}
}
void main() {
B b = new B();
A a = b.getA();
}
[/code]
Expected Output:
----
CTor 42
DTor 0
Return A
DTor 42
----
Current Output:
----
CTor 42
DTor 0
Return A
Postblit 42
DTor 84
DTor 42
----
Comment #1 by maxim — 2013-05-23T04:03:04Z
D does not have references like C++. Each time you assign return value to a struct variable, refness is wiped out. The only cases when returning by ref matter, is when returned value is also returned by caller by ref or casted to pointer.
Comment #2 by rswhite4 — 2013-05-23T04:08:43Z
I expected that in this case opAssign is called, not the postblit, beause I return by ref and assign then the ref to a new value.
But if you change A to this:
[code]
struct A {
public:
int id;
this(int id) {
writeln("CTor ", id);
this.id = id;
}
this(this) {
writeln("Postblit ", this.id);
this.id *= 2;
}
void opAssign(ref const A a) {
writeln("opAssign L: ", a.id);
this.id = a.id;
}
void opAssign(const A a) {
writeln("opAssign R ", a.id);
memcpy(&this, &a, A.sizeof);
}
~this() {
writeln("DTor ", this.id);
}
}
[/code]
You see still the same output, no call of opAssign by 'getA':
----
CTor 42
opAssign R 42
DTor 42
Return A
Postblit 42
DTor 84
DTor 42
----
Or did I miss something important here?
Comment #3 by maxim — 2013-05-23T04:14:52Z
(In reply to comment #2)
> I expected that in this case opAssign is called, not the postblit, beause I
> return by ref and assign then the ref to a new value.
Actually no, because refness here does not matter. You return by ref, but get not a ref in the caller. You don't assign ref to a new value either. You have A a = Initializer; which calls copy constructor.
Comment #4 by rswhite4 — 2013-05-23T04:18:16Z
That is absolute strange, but thanks for the explanation.