are scope guards (scope(exit, success, failure)) zero-cost abstractions?

Seb seb at wilzba.ch
Thu Feb 8 12:03:29 UTC 2018


On Thursday, 8 February 2018 at 10:44:37 UTC, Mike Parker wrote:
> On Thursday, 8 February 2018 at 10:09:12 UTC, Timothee Cour 
> wrote:
>> I'm curious whether scope guards add any cost over the naive 
>> way, eg:
>>
>> ```
>> void fun(){
>>   ...
>>   scope(success) {bar;}
>>   ...
>> }
>> ```
>>
>> vs:
>>
>> ```
>> void fun(){
>>   ...
>>   if(foo1){
>>     bar;  // add this before each return
>>     return;
>>   }
>>   ...
>>   bar;
>>   return;
>> }
>> ```
>>
>> For scope(success) and scope(failure), the naive way would 
>> anyway
>> involve try/catch statements but what about scope(exit)? Does 
>> the
>> zero-cost exception model (zero cost being for non-thrown 
>> exceptions)
>> guarantee us that scope(success) has 0 overhead over naive way?
>
> Scope guards are lowered to the equivalent try/catch/finally 
> blocks anyway.


Yes, let's look at it:


```
scope(failure) printf("%s", "error".ptr);
printf("%s", "All good.".ptr);
```

1) Lowered AST

https://run.dlang.io/is/PmRfkb

---
import object;
import core.stdc.stdio;
void main()
{
	try
	{
		printf("%s", "All good.");
	}
	catch(Throwable __o2)
	{
		printf("%s", "error");
		throw __o2;
	}
	return 0;
}
---

2) Assembly

(reduced to the interesting bits - see 
https://run.dlang.io/is/Cafgja for the full ASM)

---

		call	  printf at PLT32
		jmp short	L69
		lea	RSP,0FFFFFFF0h[RBP]
		mov	-8[RBP],EDX
		mov	RDI,RAX
		call	  __dmd_begin_catch at PLT32
		mov	-010h[RBP],RAX
		mov	EAX,-8[RBP]
		cmp	EAX,1
		je	L3F
		jmp short	L62
L3F:		lea	RSI,FLAT:.rodata[00h][RIP]
		lea	RDI,FLAT:.rodata[00h][RIP]
		xor	EAX,EAX
		call	  printf at PLT32
		mov	RDI,-010h[RBP]
		call	  _d_throwdwarf at PLT32
		mov	RSP,RBP
		pop	RBP
		ret
---


More information about the Digitalmars-d-learn mailing list