References

Namespace rswhite4 at googlemail.com
Fri Sep 20 03:35:44 PDT 2013


On Friday, 20 September 2013 at 10:29:24 UTC, andrea9940 wrote:
> On Friday, 20 September 2013 at 09:44:51 UTC, Namespace wrote:
>
>> This prints 'ref' if you change func(A a) to func(const A a) 
>> the match of const ref isn't prefered over A a because const 
>> need an implicit conversion.
> Thanks for the tip.
>
>> a + b is an rvalue and will moved to func(A a). This is even 
>> faster than ref. ;)
>> A() is also moved.
> Mmm... here is the assembly generated (with -release -O), it 
> seems to me that the struct is always copied.
>
> ; fun(a + b)
> LEA EAX,[EBP-604]
> PUSH EAX
> LEA EAX,[EBP-404]
> PUSH EAX
> LEA EAX,[EBP-804]
> CALL 00402010             ;opAdd()
> MOV EBX,EAX               ;pointer to the stack
> MOV ECX,80
> ADD EBX,1FC
> 004020C3: PUSH DWORD PTR DS:[EBX] ; copy !
> SUB EBX,4                         ; copy !
> LOOP SHORT 004020C3               ; copy !
> CALL 00402048             ; fun(const A a)
>
> ;fun(A())
> PUSH 80
> MOV EAX,OFFSET 00422930
> PUSH EAX
> CALL 00405DB0
> MOV DWORD PTR SS:[EBP-4],EAX
> MOV ECX,DWORD PTR SS:[EBP-4]
> XOR EAX,EAX
> MOV DWORD PTR DS:[ECX],EAX
> MOV EAX,DWORD PTR SS:[EBP-4]
> MOV DWORD PTR DS:[EAX+4],0
> ; a lot of movs later ...
> MOV EAX,DWORD PTR SS:[EBP-4]
> MOV DWORD PTR DS:[EAX+1FC],0
> MOV ESI,DWORD PTR SS:[EBP-4]
> LEA EDI,[EBP-204]
> MOV ECX,80
> REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
> ADD ESP,8
> ; ^ a lot of istructions to set a struct to zero imo
> LEA EBX,[EBP-8]
> MOV ECX,80
> 0040271B: PUSH DWORD PTR DS:[EBX]    ; copy !
> SUB EBX,4                            ; copy !
> LOOP SHORT 0040271B                  ; copy !
> CALL 00402048                 ;fun(const A a)
>
> ; fun(a)
> LEA EAX,[EBP-804]  ;load the reference
> CALL 00402060      ; fun(const ref A a)

If you have doubt about the assembly, please feeld free to open a 
bug report.

And for performance:
----
import std.stdio;

struct A {
public:
	uint id;
	
	this(uint id) {
		this.id = id;
		
		writeln("CTor A with ", id);
	}
	
	this(this) {
		writeln("Postblit A with ", this.id);
	}
	
	~this() {
		writeln("DTor A with ", this.id);
	}
	
	A opBinary(string op : "+")(ref const A a) {
		return A(this.id + a.id);
	}
}

void func(const A a) {
	writeln("Value call with A::", a.id);	
}

void func(ref const A a) {
	writeln("Ref call with A::", a.id);
}

void main()
{
	
	A a = A(42);
	A b = A(23);
	
	func(a + b);
	func(A(1337));
	func(a);
}
----

Output:
----
CTor A with 42
CTor A with 23
CTor A with 65
Value call with A::65
DTor A with 65
CTor A with 1337
Value call with A::1337
DTor A with 1337
Ref call with A::42
DTor A with 23
DTor A with 42
----

No Postblit call.


More information about the Digitalmars-d-learn mailing list