- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Yes, that would not be a frist.
Admin
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.
Admin
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
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
End Function
Admin
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?
Admin
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).
Admin
@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 asGOTO 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.
Admin
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>"
Admin
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.
Admin
More like, you'd need a goto, but can't use it for bureaucratic reasons.
Admin
@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.)
Admin
That's right, goto comes in handy sometimes.
Admin
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.
Admin
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"
Admin
"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
Admin
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.
Admin
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
Admin
This is what you get with coding standards that dogmatically forbid the use of "goto."
Admin
(shakes a copy of Guy Steele's "Lambda, the Ultimate Imperative") Be gone, dogmatists!
Admin
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.Admin
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.
Admin
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.
Admin
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.
Admin
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.
Admin
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?
Admin
Once again, we are reminded that WTF really stands for What The Fun.
These little snippets of code are amazing.
Admin
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.
Admin
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.
Admin
But the construct is identical to
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
Admin
Maybe it is looping; the article doesn't say.
Admin
This pattern is useful in C++ which hates jumping around initialisers. For example this would legal C but illegal C++:
With a loop and break it is legal.
Admin
There's an esolang called Come Here that also has them