- 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
"Thankfully, the fellow responsible is 'no longer with us'"
Is that because you stabbed him?
Admin
Maybe he didn't know about the "else" keyword...
Admin
Admin
Because GOTO is considered harmful, of course. Everyone knows you shouldn't use a GOTO in a modern program.
That's why people who don't understand structured programming have to simulate GOTOs with bizarre and twisted applications of other statements.
Seriously, though, this is my problem with people who insist on following a dogmatic rule without bothering to udnerstand why the rule was invented in the first place.
Hierarchy of good code:
Good: Clean structured code Bad: GOTOs Worse: Using other statements to simulate GOTOs and thus making the program even more difficult to understand than if you had just used a GOTO.
Admin
I'm surprised how many people think the solution is to use multiple RETURNs. If you're really following structured programming rules (which is the only reason I can think you'd want to avoid GOTO), then your functions should have one unconditional RETURN at the very end.
Dogma aside, function calls are more expensive than entering/exiting a loop. Maybe your compiler will fix that for you, but it won't fix that you're forcing someone reading the code to jump from place to place as they read in order to see what's going on. More functions isn't always better.
Chains of conditionals are a tough problem. I've tried various solutions, depending on the language, and I generally don't like the options.
If you really believe that sequences, conditions, and loops are the only things there are, then you can nest IF/ELSE after IF/ELSE... and I hope you have a nice, wide display terminal.
I've toyed with
if( StatementA && StatementB && StatementC ) { }
but that's a bit of an abuse of short-circuit logic.
IMO the only sane solution is to use named blocks if your language lets you BREAK from named blocks - after all, BREAK is nothing but a structured-programming compromise on the GOTO issue anyway; or to give up and use GOTO if your language won't let you use a break.
I don't like using a loop as a named block just to get a BREAK, and I'm not sure this sequence of conditionals is long enough to require that kind of solution anyway, but it hardly seems WTF-worthy.
Admin
In January I inherited code from someone who just left. It has a for-break loop like this that is 600 lines long. 600 lines of check-a-condition, set-an-error-variable and break.
It made me twitchy just looking at it. I brought it up in the weekly team meeting and everyone 10 years younger than me said, "No, we like those." Now I feel twitchy and stabby (and get-off-my-lawny).
Everyone accepts that it's wrong to have a function with multiple return points. Many code-scouring tools identify that as a problem. So, isn't multiple breaks within a loop wrong for the same reason? I'd much rather see:
bool success = true;
// Take 600 lines of crap and put it into separate condition-checker functions () if (success) success = checkConditionA ();
if (success) success = checkConditionB (); etc..
Thanks for listening to my rant. No one here will listen...
Captcha: Saepius - and they said we couldn't create a human-Octopus hybrid!
Admin
As a matter of facts, "Code Complete" even suggest this trick.
Admin
Couldn't a switch(true) have accomplished the same thing?
Admin
You know, I've done that kind of stuff… in a do { } while(0); fortunately, and for a use case more complex than that. It's useful in C code in case you have multiple temporary objects/resources allocated in the scope, that you need to clean up, as then you cannot easily refactor to put the "loop" in its own function and replace the breaks by a function return. I feel it's a restricted case of goto that's clean, as all jump at the same point, without any possibility for a labyrinth of gotos.
Admin
Almost, but not quite.
Your code would execute the for loop when the first condition was true. This would at least be wasteful and might lead to errors if !pModel meant that asModelPartsToLoad was not initialized.
Putting an the for loop into an else clause would fix that.
Admin
What's wrong with this?
Admin
NOT a WTF, this is common for Embedded systems on small 8bit micro
Admin
Admin
Admin
In C code, this is better than a case statement, especially for string operands, which are not supported.
Admin
Admin
As Ken B. mentioned it is INTERCAL. Although to be fair that language was designed to be as obtuse and evil as possible.
For real world evil check out COBOL's "ALTER" statement.
Admin
If you use else (say 12 times, with some else if's) and later remove one condition; it gets complicated.
Admin
Admin
Never heard of "else" ??
Admin
Not seeing any real WTF here. The guy's code mirrors how he thinks about the process. To be honest, it's more readable than a lot of the alternatives offered up in the comments here.
Admin
I skipped over all of the meme battles and trolling after the first 30 or so posts, so I do not know if anyone proposed this replacement yet. It eliminates the break at the end of the for loop. Forgetting that break is very dangerous as some other poster pointed out.
This is clearly a better way to perform the same task. You could even create optional, self-documenting constants shown in angle brackets. Of course make sure that none of the constants are 0!
Admin
I "I X'd your Y, pray I don't X any further"'d your post, pray I don't "I X'd your Y, pray I don't X any further" any further
But seriously, in university, we were told that multiple returns from a function were okay. Not amazingly great, but better than the alternative of setting some variable, holding it above the water until the end and returning it. Unless it made more sense to do that.
We weren't taught hard and fast rules on stuff like this, but we were encouraged to notice code smell, given on the complexity and natural form of the bit of code we were working on.
Admin
Admin
I found the problem- this line was meant to be a comment:
for (;;)
The code is designed to make you cry.
Admin
Maybe this way is better (although, this way uses goto, so if you want to use functions that return true/false you would do it differently):
Admin
Admin
TRWTF is that loops and functions are just syntactic sugar. That's why I like to use GOTO functions and push and pop all of my variables onto the stack manually.
Admin
The real WTF is that you're using variables instead of just remembering where your data is and using the address.
Admin
Not a WTF. Union rules say that you must have at least 4 breaks per function. A for loop was the only way to fulfill this requirement.
Admin
In case you can’t tell, this is a dangerous place. The fact that you insist on trying to cheat the mafia clearly shows that you’re too dead and too missing to be organizing unions.
Go away and rest in peace.
Sincerely, Bert Glanstron
Admin
You will not use GOTO! Or else...!
Admin
Hey, remember when the comments in TDWTF were less than 90% memes and talked about the code at hand?
Good times .... good times...
I vote for refactor into method suggested on the 1st page. I've seen code style guides that say "only have one return point from a function" but that's just proof those style guides need to die in a fire.
Admin
Fixed for Java
Admin
Admin
Admin
I don't know, but it seems like the point of the WTF is being missed here.
One of my persistent habits is that of trying to find the general solution. (For example, trying to come up with something that kills everything from a flea to an elephant when what I really need is to just step on the cockroach of the moment.)
I could see any of the above I guess, if there were thousands or even dozens of things to be checked in a logic sequence. (But then you probably need to refactor something a bit, right?)
In this case, there are only 3 things to check, and no structured flow violations. So it seems to me that one possible good solution for this problem is:
Now isn't that nice and readable? Even if it isn't showy?
Taking that into account, the original code author was "federalizing the simple": Used a wrecking ball to kill the cockroach. WTF!
Admin
Continuations are too general for that task. Why embed a computation in a continuation monad (which brings in zero domain related methods, specifically because of how general it is) when you can embed it in an error monad (which brings in exception methods like try, catch, etc)?
Admin
It should have been:
for (;;) {}
That's the "do-nothing-forever" construct, a metaphor for so many things in this life.
Admin
OTOH, the fact remains that most programmers aren't familiar with continuations, or even the languages which support them. This is a shame, because they really are a fascinating construct, and (like many of the tools in functional programming) knowing about them changes you perspective on what things like expressions and functions really are.
Admin
I once had to implement an isEmpty() method in JavaScript, and the only way I could find to do it in constant time was
for (item in this) { return false; } return true;
Admin
One of the reasons to use a construct like this (though I've generally thought that do{}while(0) is cleaner) is that goto statements can't skip forward over initialization.
So, if you want to localize your initializers so your code is both readable and easy to refactor, and you want to dodge having deep exit-out if blocks, a loop-based construct like this can be useful. Also remember that, in ANSI C++, goto was restricted to labels within the current block. No destructor-ness was accounted for.
do{}while(0), while it still only lets you know that it's a faux-loop at the end, at least doesn't run the risk of turning into an infinite loop if you forget to put a break in the default clause. I typically prefer it to infinite for loops.
Just put a comment at the top of the block indicating what you're up to and it's a pretty friggin' reasonable thing for anyone but a complete novice programmer.
Admin
As others have said, do{...}while(0) would be better than for(;;), but this is really not a WTF. This sort of structure is fairly common. The main advantage is that your function has a single point of exit, which can make it much easier to debug. Since you know that every part of your function will cross that point regardless of what error may have occurred, you can use that to free up any memory which may have been allocated at that single point, which makes tracking down and fixing memory leaks much easier.
Think of it as C's version of try & catch.
Admin
I guess you didn't notice that !bCreateModel in the condition of the loop. It works, unless GetSize() has some unwanted side-effect. However, I don't understand why he just didn't make the loop the else clause of the if.
Admin
Code is perfectly OK.
It avoids unnecessary testing after bCreateModel has been set, and it skips the extra test which would be required to test if bCreateModel was set before each step.
Since this is C++, it's a good rule of thumb to avoid gotos to transfer control between scopes, since any destructors that should have been run at the end of the scope won't be run.
A do { } while(0) loop is preferable, but only because you don't need to remember the final break statement.
Only WTF is blaming someone for writing bad code, because one is unfamiliar with this construct.
Admin
Admin
(In reality, I agree with you, but I have to go with the general meme of one-ups-manship and oh-yeah-ya-think-so here on the site.)
Clearly you haven't seen INTERCAL. It's very hard to not misuse any of its "features".
Furry cows moo and decompress.
Admin
If you have C at your disposal, you can just use goto.
Admin
I don't think you ever debugged an enterprise app written in DEC BASIC.
1000 Every language that has a label or line-number 1010 that you can GOTO has a COMEFROM problem. It is 1020 not the GOTO that is the problem (although a 1030 computed GOTO is a bit of a problem). GOTO 1050 1040 OK, WHERE DID THIS LINE COME FROM ? 1050 It is the come-from that is the problem.
Languages that have loop and control structures (structured programming languages) clarify how you get to each line. Structures where the conditional is implemented at the top are implicitly (GOTO 1040) COMEFROM structures. Despite what Wikepedia claims, this does not make them more difficult.
Note: this comment has a bug.
Admin
Like all good programming language features, Lisp had it first and did it better:
Not that it would actually be necessary to use this structure in Lisp, given that Lisp allows the following, much more elegant solution, which takes advantage of the built-in structural equality operator:
Captcha: odio, Spanish for "I hate". Odio Java.