www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Statement "goto" between functions

reply Andrey <saasecondbox yandex.ru> writes:
Hello,
Can anybody say - is it possible to implement in D a statement 
"goto between functions". Not between random functions but 
between functions that are currently on the stack. Such "goto" 
will be something like labeled break in nested loops.
Example of what I mean. Lets imagine call stack:
 int main			
 someFunction1 	
 someFunction2
 ... someFunctionN
and code:
 void someFunction1(T...)(T args)
 {
     // do some actions...
     someFunction2(10, true, "hello"); // nested call
     // do some actions...
     GOTO_LABEL_EXTRA1:
     writeln("Exit - GOTO_LABEL_EXTRA1 (or regular exit)");
     return;
 
     GOTO_LABEL_EXTRA2:
     writeln("Exit - GOTO_LABEL_EXTRA2");
 
     // do other actions
 }
 void someFunctionN()
 {
     // do some actions...
     if(condition) goto GOTO_LABEL_EXTRA1;
     // do other actions...
     if(othercondition) goto GOTO_LABEL_EXTRA2;
     // do some other actions...
     return; // regular exit
 }
Inside "main" we call "someFunction1" where we call "someFunction2" where we call "someFunction3" ... where we call "someFunctionN". This looks like nested loops. When we make some calculations inside "someFunctionN" we exit it. Stack is unrolled and we are again inside "someFunction1". Execution continues from label (if exit was through goto) or through regular flow. At the moment there are (as I understand) two different and non-overlapping ways to exit from function - usual "return" or exception. Exceptions are expansive and aren't suited for normal flow. Returns are ambiguous. To get rid of ambiguity one can return bool flag and then check it. But it is ugly and why I must check 10 times the same flag when in someFunctionN I know exactly result and currect branch of execution flow? I want just to jump to next instruction (and free stack and heap) without any additional runtime things. And for loops there are (as I understand) four ways in exit - return, exception, break and goto. This example we can see from another side - as if we mixin code of someFunction2 .. someFunctionN in someFunction1. What do you think?
May 25
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Saturday, 25 May 2019 at 19:29:03 UTC, Andrey wrote:
 is it possible to implement in D a statement "goto between 
 functions". Not between random functions but between functions 
 that are currently on the stack. Such "goto" will be something 
 like labeled break in nested loops.
D being a systems programming language allows basically anything you can do with assembly hacks. Here is a posix-only demo using the C standard library functions setjmp (analogous to try-catch) and longjmp (analogous to throw). https://run.dlang.io/is/aPlxfQ As you can see it is still pretty ugly, and it's absolutely not recommended to use this.
 But it is ugly and why I must check 10 times the same flag when 
 in someFunctionN I know exactly result and currect branch of 
 execution flow? I want just to jump to next instruction (and 
 free stack and heap) without any additional runtime things.
 ...
 What do you think?
I think you should either: - rethink your design - check return values manually - still use Exceptions, which is the only way of jumping over functions that is supported by the language. A long-jump solution is bad because: - your code's control flow becomes spaghetti - things like destructors, Exceptions and scope statements won't function properly anymore. - setjmp/longjmp save/restore all registers, so it's still slower than a goto - while I can't speak from experience (I haven't used them in practice), I bet they easily break, are hard to debug and are not very portable.
May 25
parent reply Andrey <saasecondbox yandex.ru> writes:
On Saturday, 25 May 2019 at 20:18:23 UTC, Dennis wrote:
 On Saturday, 25 May 2019 at 19:29:03 UTC, Andrey wrote:
 is it possible to implement in D a statement "goto between
And how to return from deep functions back some function on the surface? Directly without extra checks. Exceptions are not suitable for it.
May 26
parent Dennis <dkorpel gmail.com> writes:
On Sunday, 26 May 2019 at 17:46:55 UTC, Andrey wrote:
 And how to return from deep functions back some function on the 
 surface? Directly without extra checks.
That's what my longjmp example does. Can you tell me what you're making? I'm curious what you need this for.
May 26
prev sibling parent CasparKielwein <Caspar Kielwein.de> writes:
On Saturday, 25 May 2019 at 19:29:03 UTC, Andrey wrote:
 Hello,
 Can anybody say - is it possible to implement in D a statement 
 "goto between functions". Not between random functions but 
 between functions that are currently on the stack. Such "goto" 
 will be something like labeled break in nested loops.
 (...)
 What do you think?
If I understand you correctly, you basically want coroutines. D offers a library implementation called Fibers: https://dlang.org/library/core/thread/fiber.html They allow switching between arbitrary stack like contexts, which should enable your algorithm.
May 26