Jump to page: 1 2
Thread overview
Copy instead of reference?
May 23, 2013
Namespace
May 23, 2013
Namespace
May 23, 2013
Namespace
May 23, 2013
Artur Skawina
May 23, 2013
Namespace
May 23, 2013
Simen Kjaeraas
May 23, 2013
Namespace
May 23, 2013
Namespace
May 23, 2013
Artur Skawina
May 23, 2013
Namespace
May 23, 2013
Namespace
May 23, 2013
Maxim Fomin
May 23, 2013
Namespace
May 23, 2013
Dicebot
May 23, 2013
Artur Skawina
May 23, 2013
Namespace
May 23, 2013
Artur Skawina
May 23, 2013
I get this output:

====

----
CTor 42
DTor 0
Return A
Postblit 42
----
DTor 84
DTor 42

====

with the following code. I'm a bit confused about the Postblit. I return by ref so I thought that I get a const ref of the original A.

[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 = void;

public:
	this() {
		this._a = A(42);
	}

	ref const(A) getA() const {
		writeln("Return A");
		return this._a;
	}
}

void main() {
	writeln("----");
	B b = new B();
	A a = b.getA();
	writeln("----");
}
[/code]
May 23, 2013
Forget to say: I use dmd 2.062.
May 23, 2013
I've filled a bug report.
May 23, 2013
On 05/23/13 11:47, Namespace wrote:
> I get this output:
> 
> ====
> 
> ----
> CTor 42
> DTor 0
> Return A
> Postblit 42
> ----
> DTor 84
> DTor 42
> 
> ====
> 
> with the following code. I'm a bit confused about the Postblit. I return by ref so I thought that I get a const ref of the original A.

>     ref const(A) getA() const {
>         writeln("Return A");
>         return this._a;
>     }

>     A a = b.getA();

You do, but you then assign to another 'A'...

artur
May 23, 2013
That was what I also expected. But opAssign is not called.
May 23, 2013
On Thu, 23 May 2013 13:29:49 +0200, Namespace <rswhite4@googlemail.com> wrote:

> That was what I also expected. But opAssign is not called.

Because you have a postblit. It's called instead of opAssign.

-- 
Simen
May 23, 2013
On Thursday, 23 May 2013 at 11:31:19 UTC, Simen Kjaeraas wrote:
> On Thu, 23 May 2013 13:29:49 +0200, Namespace <rswhite4@googlemail.com> wrote:
>
>> That was what I also expected. But opAssign is not called.
>
> Because you have a postblit. It's called instead of opAssign.

[code]
import std.stdio;
import std.c.string : memcpy;

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);
	}
}

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]

Output:
----
CTor 42
opAssign R 42
DTor 42
Return A
Postblit 42
DTor 84
DTor 42
----

Postblit, no opAssign call.
May 23, 2013
To be more detailed:

I'd expected that the code with 'getA' without ref

[code]
	A getA() {
		writeln("Return A");
		return this._a;
	}
[/code]

would print this output:

----
CTor 42
opAssign R 42
DTor 42
Return A
Postblit 42
opAssign R 84
DTor 84
DTor 42
----

And with 'getA' with ref

[code]
	ref A getA() {
		writeln("Return A");
		return this._a;
	}
[/code]

would print this output:

----
CTor 42
opAssign R 42
DTor 42
Return A
opAssign L 42
DTor 42
DTor 42
----
May 23, 2013
On 05/23/13 13:34, Namespace wrote:
>     A a = b.getA();
> Postblit, no opAssign call.
> 

You're constructing, not assigning. Try reassigning 'a' to see opAssign in action. It's a bit unintuitive and easy to miss - which I did too, hence my misleading first reply - sorry.

The issue is that D has no ref vars, so you can't really keep the returned refs around, other than passing them to another func.

artur
May 23, 2013
I know that D has (sadly) no C++ references, but I still think that

A a = some_existing_A;

should call opAssign.
« First   ‹ Prev
1 2