• (nodebb)

    Now, if you check the comments on this article about an hour or two after posting, you'll see some lovely essays describing why this particular construct is the best possible option to use in certain cases, and that it's definitely not a WTF and it shouldn't be posted on this site.

    Yes, that would not be a frist.

  • TheCPUWizard (unregistered)

    YES.... The "do while" is NOT being used as a loop, but merely a scope where "break" can be defined. This is an improvement over "goto" as the target location o the control transfer is strictly defined. The construct also acts as a scoping mechanism for the work in the ellipsed out code...

    Could it be improved Certainly [nearly EVERY piece of code can - it is very hard to have code that is provably optimal]. But I would not consider this a WTF.

  • (nodebb)

    That's nothing. Here's some (heavily anonymised) code I have to contend with: When sanitized, it's doesn't look that bad - until you see it in its perverted glory in production.

    Private Function SomeFuntion() As Boolean

    Dim strSomeString            As String
    
    On Error GoTo ErrorHandler
    
    Do While True
    	If False = SomeCondition1 Then
    		SomeOperation1
    		SomeOperation2
    		Exit Do
    	End If
    
    	If True = SomeCondition2 Then
    		SomeOperation3
    	Else
    		SomeOperation4
    		Goto Procedure_Exit
    	End If
    
    	SomeOperation5
      Exit Do
    

    Loop ' GoTo Procedure_EXIT ' ErrorHandler: Call ErrorLogging(VBA_Modulename() & "SomeFunction") Resume Next

    Procedure_EXIT: Do While True ' If SomeCondition Then MessageBox("Error") Exit Do End If

    Exit Do
    

    End Function

  • LZ79LRU (unregistered)

    I blame that annoying dutchman. Had it not been for him we'd still have GOTO in all its heavenly glory and nobody would come up with crap like this. Like, can you imagine how glorious C# or Java would have been if you had long jump capable GOTO to a label anywhere else in the code? Or better yet to a file:line number pair?

  • Foo AKA Fooo (unregistered) in reply to LZ79LRU

    Oh yeah, I miss BASIC-style line numbers. Or how about RTTI for labels that allows introspection to implement real computed gotos. No actually, I want object-oriented gotos, like virtual labels that can be redefined in derived classes, getters/setters that can redirect a goto in flight, singleton label factories and goto injection for testing!

    As for the article, TRWTF would have been using "continue" to break the loop (sic).

  • WTFGuy (unregistered)

    @LZ79LRU:

    One upside to your modest proposal:

    We'd have an endless new source of WTFs & Remy would never want for material.

    For those of you too young to have known the glories of COBOL, it had GOTO. Of course it did. But they went one better ...

    It also had ALTER. Which at runtime enabled you to change the destination of any labeled GOTO in your app. So even though the source code said GOTO Label-123 later during execution that same line of source code actually executed as GOTO SomeplaceCompletelyDifferent

    In fact you could write a GOTO statement with no target in the source code at all. Just GOTO on a line by itself. That would compile fine and run fine as long as an ALTER somewhere else was executed first to point the anonymous GOTO to a legit labeled target.

    In one sense the anonymous GOTO was safer. It at least warned the reader that this was a rogue branch that could go anywhere at any time. The targeted GOTO whose target was unexpectedly dynamic was much trickier. Remember all this was done on punch cards & green bar printouts, where grepping for "ALTER" elsewhere in the 20,000 or 100,000 lines of prolixity was ... challenging.

  • Brian (unregistered)

    Oddly enough, Steve McConnell in Code Complete actually defends goto... in very limited and specific circumstances when the alternatives would be even worse. Although in this case, simply inverting the condition would be a better option: "if (!failure) return TRUE; else <handle error>"

  • (nodebb)

    Well, I ended up using setjmp/longjmp to give myself some structured error handling once. It cleaned up the code NO end.

    However that - to be fair it has some - no, sorry, it doesn't. It swaps one WTF for another.

  • Anon55 (unregistered)

    More like, you'd need a goto, but can't use it for bureaucratic reasons.

  • John Melville (unregistered) in reply to LZ79LRU

    @LZ79LRU I fear this comment may actually be more tongue-in-cheek than the author may have been aware. There is an actual (preview) feature coming in c# 12 that will allow you to replace code in far remote parts of your program based on a filename, line, and column triple.

    https://devblogs.microsoft.com/dotnet/new-csharp-12-preview-features/ (Look at the part about interceptors.)

  • Sauron (unregistered) in reply to LZ79LRU

    That's right, goto comes in handy sometimes.

  • Sauron (unregistered) in reply to TheCPUWizard

    How is it not a WTF?

    Error handling requires unconditional branching. It is fundamentally a (tiny) bit of spaghetti logic.

    You can hide it under as many constructs as you want, it is still spaghetti that you're implementing in your error handling.

    When you need a spaghetti, implement it as a spaghetti directly, don't wrap it in a mass of lasagna to hide the fundamental spaghetti nature.

  • Milo (unregistered)

    This exact kind of thing is why Golang supports goto. Go has special rules about where you can and cannot jump (you cannot jump into the scope of a new variable for example) so it isn't quite a raw unconditional jump, but it does neatly kill the need for "idiot loops"

  • Tim (unregistered) in reply to TheCPUWizard

    "This is an improvement over "goto" as the target location o the control transfer is strictly defined"

    you might as well say it's better to cut up a potato with a piece of string because if you used a knife you might use it wrongly and stick it in your eye

  • Mick (unregistered)

    In my early days as a PL/1 mainframe programmer, a mentor told me that when debugging, GoTo statements become, in effect, ComeFrom statements. Which leaves you with no concrete clue as how you got to the point where the error occurred. I took his point from then on, in my programming career.

  • (nodebb) in reply to Mick

    Amazing you mentioned that Mick, I was just about to lament the fact that even in 2023, no other language has adopted INTERCAL's COMEFROM statement. :-D

  • asdf (unregistered)

    This is what you get with coding standards that dogmatically forbid the use of "goto."

  • Duke of New York (unregistered)

    (shakes a copy of Guy Steele's "Lambda, the Ultimate Imperative") Be gone, dogmatists!

  • OldCoder (unregistered) in reply to WTFGuy

    In COBOL one use I remember was to only do initialisation once. You'd have something like the following: LABEL1: GOTO LABEL2 LABEL2: ...Initialisation code only done once... ALTER LABEL1 TO GO TO LABEL3 LABEL3: ...thus only executing the init code once. Then someone invented the setuip whereby you performed everything in sight and the ALTER statements went away.

  • guest (unregistered)

    The idea here is perfectly fine - write the happy path code all together, write error handlers off to the side. This is the whole point of things like exceptions or monadic error handling.

    The WTF is languages like C or Go that don't provide tools to actually express what you're doing in a cleanly-readable format.

  • Duke of New York (unregistered)

    TRWTF is that this code as shown didn't even have a special case for goto, since the normal exit path from the "loop" is available but unused.

    Meanwhile, if you ever see someone using this kind of "go-do" construct in Java you can promptly point them to sections 14.7 and 14.15 of the JLS, which explain that one can break out of any labeled block statement, even if it is not a loop. Presto, no more "do-while (false)" silliness and you can choose a label that helpfully describes what is broken out of.

  • (nodebb)

    Re "goto is bad mkay", I'd just like to point out that the Linux kernel code (in C) uses gotos in many places for common cleanup (which is code that's needed to properly cleanup - like freeing allocated heap memory, etc - regardless of whether or not there was an error) when errors occur. I think this is a fairly decent way to have error handling plus common cleanup without violating DRY.

    Addendum 2023-08-03 14:00: ...in languages and situations where there isn't a better alternative, that is.

  • Randal L. Schwartz (github)

    I think Perl has the right balance (if you ignore its goto). last/next/redo without a label work with the innermost "looping block", of which the naked block (curlies holding a sequence of statements) counted as a looping block. To jump around with an outer block, just add a label. Often we add an unnecessary label to a block of the noun of the thing it's processing like "LINE" or "ITEM". Then last LINE, next ITEM, redo LINE make sense.

  • LZ79LRU (unregistered) in reply to Foo AKA Fooo

    Exactly. Basically a modernized reflection enabled object oriented (and functional if you want, of course) COBOL-like GOTO syntax. Like imagine implementing a system where the flow is entirely controlled by GOTO statements being fed labels via a command pattern from several different inputs. Wouldn't that just be swell?

  • (nodebb)

    Once again, we are reminded that WTF really stands for What The Fun.

    These little snippets of code are amazing.

  • Erik (unregistered) in reply to OldCoder

    I see your ALTERs and I raise you a PERFORM ... THRU.

    For the uninitiated, COBOL allows a calling routine - at will - to define the start and end point of a sequence of PROCEDUREs that should be executed. One caller might PERFORM A THRU E, while another might PERFORM C THRU G. Yes, C D and E are the same procedures executed in both overlapping ranges. Do not think of C D and E as isolated functions - they are, essentially, blocks of code in the same function.

    And the caller gets to decide which ones are executed ...

    PERFORM ... THRU and ALTER are two of the biggest headaches for COBOL-to-C source translators.

  • Officer Johnny Holzkopf (unregistered)
    Comment held for moderation.
  • where can i get accutane in australia (unregistered)
    Comment held for moderation.
  • LZ79LRU (unregistered) in reply to Erik
    Comment held for moderation.
  • Bob (unregistered)

    do { ... } while (0) is a common idiom in C macros, and breaking out of it can be useful sometimes. (I know, macros are their own kind of evil, but they are sometimes very useful.) And in a macro, a break is better than a goto because you don't need to come up with a unique label for a break.

  • (nodebb) in reply to TheCPUWizard

    But the construct is identical to

    if (!failureCondition)
    {
        // Happy path
       return true;
    }
    
    // failure handling
    

    except it repurposes do ... while. I submit the code above is cleaner and easier to understand than the code in the article.

    Addendum 2023-08-11 07:23: except it DOES NOT repurpose do ... while

  • John (unregistered)

    Maybe it is looping; the article doesn't say.

  • Gnasher729 (unregistered)

    This pattern is useful in C++ which hates jumping around initialisers. For example this would legal C but illegal C++:

    If (cond) goto errorhandling;
    Int I = 0;
    

    With a loop and break it is legal.

  • JW (unregistered) in reply to Bim Zively

    There's an esolang called Come Here that also has them

Leave a comment on “Error While you Wait”

Log In or post as a guest

Replying to comment #:

« Return to Article