Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
On Thursday, 8 February 2018 at 11:23:43 UTC, Daniel Kozak wrote: I mean scope(success), for scope(exit) there is no speed penalty On Thu, Feb 8, 2018 at 12:03 PM, Daniel Kozak wrote: Yes, it add, but is almost zero On Thu, Feb 8, 2018 at 12:00 PM, Timothee Cour via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: I know that, my question is whether it adds any runtime overhead over naive way (which is to call the "bar" finalizer before each return statement) in the case where no exception is thrown On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn 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, it's easy to see this when looking at the lowered AST and ASM. 1) AST https://run.dlang.io/is/KNJbnP --- import object; import core.stdc.stdio; void main() { printf("%s", "All good."); printf("%s", "FOO"); return 0; } --- 2) ASM https://run.dlang.io/is/bIVYvi --- _Dmain: pushRBP mov RBP,RSP lea RSI,FLAT:.rodata[00h][RIP] lea RDI,FLAT:.rodata[00h][RIP] xor EAX,EAX call printf@PLT32 lea RSI,FLAT:.rodata[00h][RIP] lea RDI,FLAT:.rodata[00h][RIP] xor EAX,EAX call printf@PLT32 xor EAX,EAX pop RBP ret ---
Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
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@PLT32 jmp short L69 lea RSP,0FFF0h[RBP] mov -8[RBP],EDX mov RDI,RAX call __dmd_begin_catch@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@PLT32 mov RDI,-010h[RBP] call _d_throwdwarf@PLT32 mov RSP,RBP pop RBP ret ---
Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
Yes, it add, but is almost zero On Thu, Feb 8, 2018 at 12:00 PM, Timothee Cour via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > I know that, my question is whether it adds any runtime overhead over > naive way (which is to call the "bar" finalizer before each return > statement) in the case where no exception is thrown > > > On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn > 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. >
Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
I mean scope(success), for scope(exit) there is no speed penalty On Thu, Feb 8, 2018 at 12:03 PM, Daniel Kozak wrote: > Yes, it add, but is almost zero > > On Thu, Feb 8, 2018 at 12:00 PM, Timothee Cour via Digitalmars-d-learn < > digitalmars-d-learn@puremagic.com> wrote: > >> I know that, my question is whether it adds any runtime overhead over >> naive way (which is to call the "bar" finalizer before each return >> statement) in the case where no exception is thrown >> >> >> On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn >> 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. >> > >
Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
I know that, my question is whether it adds any runtime overhead over naive way (which is to call the "bar" finalizer before each return statement) in the case where no exception is thrown On Thu, Feb 8, 2018 at 2:44 AM, Mike Parker via Digitalmars-d-learn 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.
Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
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.
Re: are scope guards (scope(exit, success, failure)) zero-cost abstractions?
likewise, will scope(exit) add any overhead over naive code in the case where no exception is thrown? ``` void fun(){ ... scope(success) {bar;} ... } vs void fun(){ ... if(foo1){ bar; // add this before each return return; } ... bar; return; } ``` On Thu, Feb 8, 2018 at 2:09 AM, 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?
are scope guards (scope(exit, success, failure)) zero-cost abstractions?
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?