digitalmars.D - goto a no-go?
- Chris (26/26) Oct 01 2013 Just a short question. Usually goto statements are frowned upon
- Dicebot (3/10) Oct 01 2013 Have never felt need to use `goto` since got familiar with
- Chris (5/18) Oct 01 2013 Thanks, this is what I was looking for, a more elegant solution.
- Dicebot (5/9) Oct 01 2013 goto is not avoided because of functionality it enables but
- Chris (2/11) Oct 01 2013 That was my point.
- Jesse Phillips (7/20) Oct 02 2013 if (word.length)
- Dicebot (3/10) Oct 02 2013 Oops, shame on me. Too many `static if`s in my life :(
- monarch_dodra (4/17) Oct 02 2013 I think it might be a common mistake? I remember making a similar
- Andrei Alexandrescu (4/15) Oct 02 2013 I think it's a common mishap. Might be nice if the compiler disallowed
- deadalnix (3/22) Oct 02 2013 Or more generally cope statement at the end of a scope.
- Andrei Alexandrescu (25/46) Oct 02 2013 I'm cautious about that; that's why I specified "unbraced". Consider:
- deadalnix (5/17) Oct 02 2013 It is also fairly common to add control flow that make code
- Dmitry Olshansky (6/28) Oct 11 2013 Truth be told I'd be _very_ cautious of the tiny special cases like
- qznc (13/39) Oct 01 2013 How is that transformation an optimization or improvement?
- Manu (18/43) Oct 01 2013 Well, obviously that should be rewritten:
- John Colvin (9/15) Oct 01 2013 labeled statements to the rescue!
- monarch_dodra (43/58) Oct 01 2013 break outer; Obsoletes one of my "only" use cases where before, I
- Dicebot (2/2) Oct 01 2013 Can't you use scope guards for that too? Those work for any
- monarch_dodra (6/8) Oct 01 2013 I hadn't thought of that before, but I don't think so. scope
- Dicebot (5/13) Oct 01 2013 In that case you can always replace "control block + goto" with
- monarch_dodra (13/30) Oct 01 2013 I was going to say: "but using functions is a pain when you have
- Nick Treleaven (10/12) Oct 02 2013 Although it might not get used that often, it might be nice if D allowed...
- Chris (7/74) Oct 01 2013 That was just a made up example (of an obvious case). The real
- deadalnix (8/18) Oct 01 2013 BreakableLoop: while(condition) {
- Manu (4/19) Oct 01 2013 ... O_O
- monarch_dodra (3/30) Oct 01 2013 Yup :)
- deadalnix (2/29) Oct 01 2013 Yes, I use it quite a lot ! Very useful construct.
- Manu (4/32) Oct 01 2013 Super useful! :)
- Dicebot (6/8) Oct 01 2013 http://dlang.org/statement.html#BreakStatement
- Jakob Ovrum (10/11) Oct 01 2013 It's best viewed as a compatibility or micro-optimization
- Jos van Uden (6/7) Oct 01 2013 I doubt it's necessary but it can be useful sometimes. In the Markov
- Gary Willoughby (5/8) Oct 01 2013 News to me! I haven't used goto in 15 years of development as
- Unknown (9/12) Oct 01 2013 I use break SomeLabel for this situations:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (49/49) Oct 01 2013 Nobody mentioned the use of goto with switch-case.
- monarch_dodra (3/9) Oct 01 2013 Hum... What is the difference between "goto case" and "continue"
- monarch_dodra (4/17) Oct 01 2013 Never-mind, I seem to have been confused. I thought "continue"
- Jakob Ovrum (4/5) Oct 01 2013 Those are goto-case statements, not goto statements. I don't
- monarch_dodra (17/22) Oct 02 2013 Well, it remains a "go to this piece of code" command.
- Gary Willoughby (2/3) Oct 02 2013 No it isn't, that is awful code.
- Walter Bright (4/6) Oct 01 2013 Actually, the dmd compiler turns ALL control flow into goto statements
- deadalnix (2/10) Oct 01 2013 Most compiler do that.
Just a short question. Usually goto statements are frowned upon as being bad programming style (in textbooks at least). D has it (thankfully) and I've used it, albeit sparingly. Sometimes goto is simply the best and most efficient solution within a code block (to avoid code duplication, unnecessary checks or redirecting to yet another function blah blah). Is it ok or even necessary to use goto in D? Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like this // ... if (word.length == 1) { // format output return output; } else if (word.length > 1) { // do some additional processing // format output return output; } into // ... if (word.length == 1) goto FormatOutput; // if word.length > 1, some extra work has to be done // initialize some variables, parse, do some processing etc. FormatOutput: // ..... return output;
Oct 01 2013
// ... if (word.length == 1) goto FormatOutput; // if word.length > 1, some extra work has to be done // initialize some variables, parse, do some processing etc. FormatOutput: // ..... return output;Have never felt need to use `goto` since got familiar with `scope(something)` : http://dpaste.dzfl.pl/ca40b3b6 ;)
Oct 01 2013
On Tuesday, 1 October 2013 at 11:26:54 UTC, Dicebot wrote:Thanks, this is what I was looking for, a more elegant solution. I was going through some old code and saw the odd goto statement. scope() shows of course that some sort of goto mechanism is pretty handy (no matter what the textbooks say).// ... if (word.length == 1) goto FormatOutput; // if word.length > 1, some extra work has to be done // initialize some variables, parse, do some processing etc. FormatOutput: // ..... return output;Have never felt need to use `goto` since got familiar with `scope(something)` : http://dpaste.dzfl.pl/ca40b3b6 ;)
Oct 01 2013
On Tuesday, 1 October 2013 at 11:35:35 UTC, Chris wrote:Thanks, this is what I was looking for, a more elegant solution. I was going through some old code and saw the odd goto statement. scope() shows of course that some sort of goto mechanism is pretty handy (no matter what the textbooks say).goto is not avoided because of functionality it enables but because of unhygienic way it is implemented. scope guards offer part of that functionality in much more clean and safe way and there is nothing wrong about using them.
Oct 01 2013
On Tuesday, 1 October 2013 at 12:13:18 UTC, Dicebot wrote:On Tuesday, 1 October 2013 at 11:35:35 UTC, Chris wrote:That was my point.Thanks, this is what I was looking for, a more elegant solution. I was going through some old code and saw the odd goto statement. scope() shows of course that some sort of goto mechanism is pretty handy (no matter what the textbooks say).goto is not avoided because of functionality it enables but because of unhygienic way it is implemented. scope guards offer part of that functionality in much more clean and safe way and there is nothing wrong about using them.
Oct 01 2013
On Tuesday, 1 October 2013 at 11:26:54 UTC, Dicebot wrote:if (word.length) scope(exit) FormatOutput(); This is the same as if (word.length) FormatOutput(); The `if` introduces a new scope, thus running the code right away.// ... if (word.length == 1) goto FormatOutput; // if word.length > 1, some extra work has to be done // initialize some variables, parse, do some processing etc. FormatOutput: // ..... return output;Have never felt need to use `goto` since got familiar with `scope(something)` : http://dpaste.dzfl.pl/ca40b3b6 ;)
Oct 02 2013
On Wednesday, 2 October 2013 at 16:12:58 UTC, Jesse Phillips wrote:if (word.length) scope(exit) FormatOutput(); This is the same as if (word.length) FormatOutput(); The `if` introduces a new scope, thus running the code right away.Oops, shame on me. Too many `static if`s in my life :(
Oct 02 2013
On Wednesday, 2 October 2013 at 17:06:40 UTC, Dicebot wrote:On Wednesday, 2 October 2013 at 16:12:58 UTC, Jesse Phillips wrote:I think it might be a common mistake? I remember making a similar error by placing a scope(exit) in a for loop, hoping they'd all get run when leaving the function.if (word.length) scope(exit) FormatOutput(); This is the same as if (word.length) FormatOutput(); The `if` introduces a new scope, thus running the code right away.Oops, shame on me. Too many `static if`s in my life :(
Oct 02 2013
On 10/2/13 10:06 AM, Dicebot wrote:On Wednesday, 2 October 2013 at 16:12:58 UTC, Jesse Phillips wrote:I think it's a common mishap. Might be nice if the compiler disallowed gramatically an unbraced if/while/etc containing only one scope statement. Andreiif (word.length) scope(exit) FormatOutput(); This is the same as if (word.length) FormatOutput(); The `if` introduces a new scope, thus running the code right away.Oops, shame on me. Too many `static if`s in my life :(
Oct 02 2013
On Thursday, 3 October 2013 at 02:21:19 UTC, Andrei Alexandrescu wrote:On 10/2/13 10:06 AM, Dicebot wrote:Or more generally cope statement at the end of a scope.On Wednesday, 2 October 2013 at 16:12:58 UTC, Jesse Phillips wrote:I think it's a common mishap. Might be nice if the compiler disallowed gramatically an unbraced if/while/etc containing only one scope statement. Andreiif (word.length) scope(exit) FormatOutput(); This is the same as if (word.length) FormatOutput(); The `if` introduces a new scope, thus running the code right away.Oops, shame on me. Too many `static if`s in my life :(
Oct 02 2013
On 10/2/13 8:14 PM, deadalnix wrote:On Thursday, 3 October 2013 at 02:21:19 UTC, Andrei Alexandrescu wrote:I'm cautious about that; that's why I specified "unbraced". Consider: if (lily) { scope(exit) writeln("Lily was here."); // fun(); } This code is a plausible edit of work that was meaningful and in which the programmer has temporarily commented out the call to fun. If the compiler would obnoxiously protest that the edited code can't compile, that may be more aggravation than win for the user. In contrast, this is no simple edit of any sensible code: if (lily) scope(exit) writeln("Lily was here."); Here, the compiler is much more within its rights to demand a code change, either to scope(exit) if (lily) writeln("Lily was here."); or if (lily) writeln("Lily was here."); or if (lily) { scope(exit) writeln("Lily was here."); } AndreiOn 10/2/13 10:06 AM, Dicebot wrote:Or more generally cope statement at the end of a scope.On Wednesday, 2 October 2013 at 16:12:58 UTC, Jesse Phillips wrote:I think it's a common mishap. Might be nice if the compiler disallowed gramatically an unbraced if/while/etc containing only one scope statement. Andreiif (word.length) scope(exit) FormatOutput(); This is the same as if (word.length) FormatOutput(); The `if` introduces a new scope, thus running the code right away.Oops, shame on me. Too many `static if`s in my life :(
Oct 02 2013
On Thursday, 3 October 2013 at 03:37:27 UTC, Andrei Alexandrescu wrote:I'm cautious about that; that's why I specified "unbraced". Consider: if (lily) { scope(exit) writeln("Lily was here."); // fun(); } This code is a plausible edit of work that was meaningful and in which the programmer has temporarily commented out the call to fun. If the compiler would obnoxiously protest that the edited code can't compile, that may be more aggravation than win for the user.It is also fairly common to add control flow that make code unrechable in dev (or when playing with static ifs). And it is disallowed.
Oct 02 2013
03-Oct-2013 07:37, Andrei Alexandrescu пишет:On 10/2/13 8:14 PM, deadalnix wrote:[snip]On Thursday, 3 October 2013 at 02:21:19 UTC, Andrei Alexandrescu wrote:On 10/2/13 10:06 AM, Dicebot wrote:Truth be told I'd be _very_ cautious of the tiny special cases like this, they make generating D code (including at CTFE) a PITA. -- Dmitry OlshanskyOr more generally cope statement at the end of a scope.I'm cautious about that; that's why I specified "unbraced". Consider: if (lily) { scope(exit) writeln("Lily was here."); // fun(); } This code is a plausible edit of work that was meaningful and in which the programmer has temporarily commented out the call to fun. If the compiler would obnoxiously protest that the edited code can't compile, that may be more aggravation than win for the user. In contrast, this is no simple edit of any sensible code: if (lily) scope(exit) writeln("Lily was here."); Here, the compiler is much more within its rights to demand a code change, either to scope(exit) if (lily) writeln("Lily was here."); or if (lily) writeln("Lily was here.");
Oct 11 2013
On Tuesday, 1 October 2013 at 11:22:12 UTC, Chris wrote:Just a short question. Usually goto statements are frowned upon as being bad programming style (in textbooks at least). D has it (thankfully) and I've used it, albeit sparingly. Sometimes goto is simply the best and most efficient solution within a code block (to avoid code duplication, unnecessary checks or redirecting to yet another function blah blah). Is it ok or even necessary to use goto in D? Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like this // ... if (word.length == 1) { // format output return output; } else if (word.length > 1) { // do some additional processing // format output return output; } into // ... if (word.length == 1) goto FormatOutput; // if word.length > 1, some extra work has to be done // initialize some variables, parse, do some processing etc. FormatOutput: // ..... return output;How is that transformation an optimization or improvement? Substituting "return output" for "goto FormatOutput" is not better. So, I assume "// format output" is the code duplication you want to remove? Well, your example should also work like this: if (word.length > 1) { // do some additional processing } // format output return output; Regarding goto and D, scope guards [0] are good for removing gotos, because the cleanup-after-error code can be moved. [0] http://dlang.org/statement.html#ScopeGuardStatement
Oct 01 2013
On 1 October 2013 21:22, Chris <wendlec tcd.ie> wrote:Just a short question. Usually goto statements are frowned upon as being bad programming style (in textbooks at least). D has it (thankfully) and I've used it, albeit sparingly. Sometimes goto is simply the best and most efficient solution within a code block (to avoid code duplication, unnecessary checks or redirecting to yet another function blah blah). Is it ok or even necessary to use goto in D? Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like this // ... if (word.length == 1) { // format output return output; } else if (word.length > 1) { // do some additional processing // format output return output; } into // ... if (word.length == 1) goto FormatOutput; // if word.length > 1, some extra work has to be done // initialize some variables, parse, do some processing etc. FormatOutput: // ..... return output;Well, obviously that should be rewritten: if (word.length > 1) { // additional processing } // format output return output; Note: there's an un-handled case in your example, but I'll ignore that. Anyway, goto is supported. Walter likes it. I use it from time to time. I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem. But in direct answer to your question, I think you'll find modern optimisers are smart enough to make the optimisation you are looking for. I haven't tested that precise case, but I've definitely expected the optimiser to do the right thing in similar cases, and it does. I rarely write code that requires me to have faith in any optimiser though.
Oct 01 2013
On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem.labeled statements to the rescue! outer: foreach(i; 0..10) { foreach(j; 0..10) { break outer; } }
Oct 01 2013
On Tuesday, 1 October 2013 at 11:47:37 UTC, John Colvin wrote:On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:break outer; Obsoletes one of my "only" use cases where before, I would have used a goto instead: foreach(i; 0..10) { foreach(j; 0..10) { goto double_break; } } double_break: {} It's awesome. Too bad you can't break from an arbitrary block though. It can help avoiding the dreaded "if(if(if(if(...))))" pattern, as well as the "bool didYouDoIt" pattern. I still have to use my "goto after_block" pattern :/ //---- //Search and deal with a specific condition //While doing something special if the condition is not found. { if (some_condition) goto block_end; //No need to do anything if (some_other_condition) goto block_end; //No need to do anything if (some_third_condition) goto block_end; //No need to do anything for (...) { for (...) { if (...) { do_processing(); goto block_end; //We found what we wanted. } } } do_code_for_not_found_here(); } done_processing: {} //Keep going here //---- I guess I can always use the "do{}while(false);" pattern, but I actually find it *more* confusing (IMO)I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem.labeled statements to the rescue! outer: foreach(i; 0..10) { foreach(j; 0..10) { break outer; } }
Oct 01 2013
Can't you use scope guards for that too? Those work for any scope, not only function scope.
Oct 01 2013
On Tuesday, 1 October 2013 at 12:46:50 UTC, Dicebot wrote:Can't you use scope guards for that too? Those work for any scope, not only function scope.I hadn't thought of that before, but I don't think so. scope guards are designed to run a specific piece of code, no mater the code path. What I mostly want to do is just break out of a "control block". Either that, or I'm being retarded...?
Oct 01 2013
On Tuesday, 1 October 2013 at 13:02:56 UTC, monarch_dodra wrote:On Tuesday, 1 October 2013 at 12:46:50 UTC, Dicebot wrote:In that case you can always replace "control block + goto" with nested function + return + scope guard inside it (if some cleanup code needs to be run) unless I am missing something. (I think your snippet misses actual labels so it was unclear:))Can't you use scope guards for that too? Those work for any scope, not only function scope.I hadn't thought of that before, but I don't think so. scope guards are designed to run a specific piece of code, no mater the code path. What I mostly want to do is just break out of a "control block". Either that, or I'm being retarded...?
Oct 01 2013
On Tuesday, 1 October 2013 at 13:09:01 UTC, Dicebot wrote:On Tuesday, 1 October 2013 at 13:02:56 UTC, monarch_dodra wrote:Right, sorry.On Tuesday, 1 October 2013 at 12:46:50 UTC, Dicebot wrote:(I think your snippet misses actual labels so it was unclear:))Can't you use scope guards for that too? Those work for any scope, not only function scope.I hadn't thought of that before, but I don't think so. scope guards are designed to run a specific piece of code, no mater the code path. What I mostly want to do is just break out of a "control block". Either that, or I'm being retarded...?In that case you can always replace "control block + goto" with nested function + return + scope guard inside it (if some cleanup code needs to be run) unless I am missing something.I was going to say: "but using functions is a pain when you have variables that are in scope you need to reuse", but I keep forgetting that D can indeed nest functions. The only "limitation" of using a nested function, as opposed to a "breakable block", is that can't move code into a nested function, if it contains a (conditional) return. I guess the conclusion is that each code snippet is unique. With enough effort, you can probably eliminate goto from almost any example. I do find that sometimes, you tend to have to jump through hoops for that tough, and the final code is not necessarily "better" either.
Oct 01 2013
On 01/10/2013 13:36, monarch_dodra wrote:I guess I can always use the "do{}while(false);" pattern, but I actually find it *more* confusing (IMO)Although it might not get used that often, it might be nice if D allowed omitting the 'while(false)' part, just using a semi-colon for 'do' termination: do { ... if (cond) break; // exit do ... // implicit fall through, no looping unless 'continue' is used };
Oct 02 2013
On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:On 1 October 2013 21:22, Chris <wendlec tcd.ie> wrote:Just a short question. Usually goto statements are frowned upon as being bad programming style (in textbooks at least). D has it (thankfully) and I've used it, albeit sparingly. Sometimes goto is simply the best and most efficient solution within a code block (to avoid code duplication, unnecessary checks or redirecting to yet another function blah blah). Is it ok or even necessary to use goto in D? Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like this // ... if (word.length == 1) { // format output return output; } else if (word.length > 1) { // do some additional processing // format output return output; } into // ... if (word.length == 1) goto FormatOutput; // if word.length > 1, some extra work has to be done // initialize some variables, parse, do some processing etc. FormatOutput: // ..... return output;Well, obviously that should be rewritten: if (word.length > 1) { // additional processing } // format output return output;Note: there's an un-handled case in your example, but I'll ignore that.That was just a made up example (of an obvious case). The real case was a bit more complicated (involving an associative array).Anyway, goto is supported. Walter likes it. I use it from time to time. I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem. But in direct answer to your question, I think you'll find modern optimisers are smart enough to make the optimisation you are looking for. I haven't tested that precise case, but I've definitely expected the optimiser to do the right thing in similar cases, and it does. I rarely write code that requires me to have faith in any optimiser though.Sure, but it's good to know that some sub-optimal code is optimized, until I find the time to optimize it by hand. Optimizing too early can be more harmful than sub-optimal code (that is just a wee bit slower but harmless).
Oct 01 2013
On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:Note: there's an un-handled case in your example, but I'll ignore that. Anyway, goto is supported. Walter likes it. I use it from time to time. I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem.BreakableLoop: while(condition) { while(condition) { // Stuff . . . break BreakableLoop; } } Also works with continue.
Oct 01 2013
On 1 October 2013 23:54, deadalnix <deadalnix gmail.com> wrote:On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:... O_O Is this D code? I've never seen that. If that works, that's awesome!Note: there's an un-handled case in your example, but I'll ignore that. Anyway, goto is supported. Walter likes it. I use it from time to time. I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem.BreakableLoop: while(condition) { while(condition) { // Stuff . . . break BreakableLoop; } } Also works with continue.
Oct 01 2013
On Tuesday, 1 October 2013 at 16:55:12 UTC, Manu wrote:On 1 October 2013 23:54, deadalnix <deadalnix gmail.com> wrote:Yup :)On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:... O_O Is this D code?Note: there's an un-handled case in your example, but I'll ignore that. Anyway, goto is supported. Walter likes it. I use it from time to time. I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem.BreakableLoop: while(condition) { while(condition) { // Stuff . . . break BreakableLoop; } } Also works with continue.I've never seen that. If that works, that's awesome!Yup :)
Oct 01 2013
On Tuesday, 1 October 2013 at 16:55:12 UTC, Manu wrote:On 1 October 2013 23:54, deadalnix <deadalnix gmail.com> wrote:Yes, I use it quite a lot ! Very useful construct.On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:... O_O Is this D code? I've never seen that. If that works, that's awesome!Note: there's an un-handled case in your example, but I'll ignore that. Anyway, goto is supported. Walter likes it. I use it from time to time. I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem.BreakableLoop: while(condition) { while(condition) { // Stuff . . . break BreakableLoop; } } Also works with continue.
Oct 01 2013
On 2 October 2013 03:00, deadalnix <deadalnix gmail.com> wrote:On Tuesday, 1 October 2013 at 16:55:12 UTC, Manu wrote:Super useful! :) Well, I think there's almost no reason left for goto... I can't think of any of my common use cases that aren't satisfied with a proper D construct.On 1 October 2013 23:54, deadalnix <deadalnix gmail.com> wrote: On Tuesday, 1 October 2013 at 11:40:35 UTC, Manu wrote:Yes, I use it quite a lot ! Very useful construct.Note: there's an un-handled case in your example, but I'll ignore that.... O_O Is this D code? I've never seen that. If that works, that's awesome!Anyway, goto is supported. Walter likes it. I use it from time to time. I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem. BreakableLoop: while(condition) {while(condition) { // Stuff . . . break BreakableLoop; } } Also works with continue.
Oct 01 2013
On Tuesday, 1 October 2013 at 16:55:12 UTC, Manu wrote:Is this D code? I've never seen that. If that works, that's awesome!http://dlang.org/statement.html#BreakStatement "If break is followed by Identifier, the Identifier must be the label of an enclosing while, for, do or switch statement, and that statement is exited. It is an error if there is no such statement."
Oct 01 2013
On Tuesday, 1 October 2013 at 11:22:12 UTC, Chris wrote:Is it ok or even necessary to use goto in D?It's best viewed as a compatibility or micro-optimization feature. For structuring code, D obsoletes goto with nested functions, scope statements and labelled break and continue. Most experienced D programmers use scope statements and labelled break/continue to replace goto with great effect, but sometimes the same programmers can still be seen using goto when a nested function would really have solved the issue more structurally, so I recommend experimenting with nested functions if they are unfamiliar to you.
Oct 01 2013
On 1-10-2013 13:22, Chris wrote:Is it ok or even necessary to use goto in D?I doubt it's necessary but it can be useful sometimes. In the Markov algorithm at Rosetta code I used it to restart a loop, including reinitializing a variable. I'm sure it could have been done without goto but it was convenient. http://rosettacode.org/wiki/Markov_Algorithm#D
Oct 01 2013
On Tuesday, 1 October 2013 at 11:22:12 UTC, Chris wrote:Sometimes goto is simply the best and most efficient solution within a code block (to avoid code duplication, unnecessary checks or redirecting to yet another function blah blah).News to me! I haven't used goto in 15 years of development as there are always more elegant ways of designing software. The only reason i can see goto being properly used is in machine generated code where no developer will be maintaining it.
Oct 01 2013
Manu píše v Út 01. 10. 2013 v 21:40 +1000:I'd say 90% of the time I find goto useful is when I need to bail from nested loops. I've often wondered if something like break(2) would be a more elegant solution to the breaking out of nested loops problem.I use break SomeLabel for this situations: FirstLoop: while(1) { SecondLoop: while(1) { break FirstLoop; } }
Oct 01 2013
Nobody mentioned the use of goto with switch-case. http://ddili.org/ders/d.en/switch_case.html goto can appear in three ways under case sections: * 'goto case' causes the execution to continue to the next case. * 'goto default' causes the execution to continue to the default section. * 'goto expression' causes the execution to continue to the case that matches that expression. The following program demonstrates these three uses by taking advantage of a foreach loop: import std.stdio; void main() { foreach (value; [ 1, 2, 3, 10, 20 ]) { writefln("--- value: %s ---", value); switch (value) { case 1: writeln("case 1"); goto case; case 2: writeln("case 2"); goto case 10; case 3: writeln("case 3"); goto default; case 10: writeln("case 10"); break; default: writeln("default"); break; } } } The output: --- value: 1 --- case 1 case 2 case 10 --- value: 2 --- case 2 case 10 --- value: 3 --- case 3 default --- value: 10 --- case 10 --- value: 20 --- default Ali
Oct 01 2013
On Tuesday, 1 October 2013 at 17:15:34 UTC, Ali Çehreli wrote:Nobody mentioned the use of goto with switch-case. http://ddili.org/ders/d.en/switch_case.html goto can appear in three ways under case sections: * 'goto case' causes the execution to continue to the next case. [SNIP] AliHum... What is the difference between "goto case" and "continue" in a switch statement?
Oct 01 2013
On Tuesday, 1 October 2013 at 19:45:20 UTC, monarch_dodra wrote:On Tuesday, 1 October 2013 at 17:15:34 UTC, Ali Çehreli wrote:Never-mind, I seem to have been confused. I thought "continue" was the keyword to use for explicit fall-through. Carry on then.Nobody mentioned the use of goto with switch-case. http://ddili.org/ders/d.en/switch_case.html goto can appear in three ways under case sections: * 'goto case' causes the execution to continue to the next case. [SNIP] AliHum... What is the difference between "goto case" and "continue" in a switch statement?
Oct 01 2013
On Tuesday, 1 October 2013 at 17:15:34 UTC, Ali Çehreli wrote:Nobody mentioned the use of goto with switch-case.Those are goto-case statements, not goto statements. I don't think it's a useful notion to associate the two beyond the fact that they share a keyword in their syntax.
Oct 01 2013
On Wednesday, 2 October 2013 at 06:19:24 UTC, Jakob Ovrum wrote:On Tuesday, 1 October 2013 at 17:15:34 UTC, Ali Çehreli wrote:Well, it remains a "go to this piece of code" command. Now, you can write a program as a single giant switch that jumps around from state to state, without it ever ending. Like in one of those "read your own adventure books" int page = 1; switch(1) { case 1: writeln("you arrive in a large chamber... To light a torch, go to page 196) To run through, go to page 155"; readfln("%s", &page); goto page; etc... } That's a pretty sweet construct actually :)Nobody mentioned the use of goto with switch-case.Those are goto-case statements, not goto statements. I don't think it's a useful notion to associate the two beyond the fact that they share a keyword in their syntax.
Oct 02 2013
On Wednesday, 2 October 2013 at 08:15:04 UTC, monarch_dodra wrote:That's a pretty sweet construct actually :)No it isn't, that is awful code.
Oct 02 2013
On 10/1/2013 4:22 AM, Chris wrote:Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like thisActually, the dmd compiler turns ALL control flow into goto statements internally, then the optimizer works on that. For example, it reverse engineers loops from a graph of basic blocks connected by goto's.
Oct 01 2013
On Tuesday, 1 October 2013 at 18:47:27 UTC, Walter Bright wrote:On 10/1/2013 4:22 AM, Chris wrote:Most compiler do that.Or does the compiler recognize _obvious_ cases and generate code accordingly? For example would it turn something like thisActually, the dmd compiler turns ALL control flow into goto statements internally, then the optimizer works on that. For example, it reverse engineers loops from a graph of basic blocks connected by goto's.
Oct 01 2013