- 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
"On Error Resume Next"? Bah, luxury! Back in my day (okay, my very very very early days), all we had was "TRAP line number".
Actually, that worked pretty damn well for an 8K BASIC. Consider:
10 TRAP 30 20 disk I/O or whatever:GOTO 40 30 clear trap:check error code:do something 40 PRINT "YAY!"
VS
try { disk I/O or whatever } catch(e) { check error code; do something } os.core.util.io.terminal.line.output(String.concatenize("YAY!", os.core.util.io.terminal.localizedLinefeed()), UTF8)
Admin
This sounds like an echo of some religious war.
But I will say that I agree that goto's weren't that bad. A little over a decade ago, I was brought in to maintain a C (not C++) program -- actually a suite of programs that used socket-level IPC -- that was maybe a few 100K lines of code. Goto's were common, but only for error handling; for example:
where the end: label marked any cleanup stuff (deallocating memory, etc) that had to be done before the function could return.As someone who had to maintain the code, I was able to quickly and easily understand what the author was trying to do, and why. No spagetti, no artificial branches to get in the way of what's really supposed to happen, only one exit point -- I found it very easy to maintain. Yes, it creates a break in your train of thought, but that's not a bad thing when dealing with errors. It also makes it relatively painless to add even more error checking to the code. Even now, I find that sort of construct simpler (and therefore easier to maintain) than throwing/catching exceptions.
Goto's can be easily abused -- in fact, I would consider using them in just about any other way to be abuse. But when used as above, I can say from experience it leads to easily-maintained code.
Admin
It seems to me like opposition to GOTOs has become one of those unshakable dogmas that may not be questioned. Someone says, "Look, wouldn't this program be cleaner if we just used a goto here?" And the reply is always, "NO! Gotos are evil! You can avoid using the goto by just writing a hundred lines of incomprehensible code!"
The question should not be, Is it possible to solve the problem without using a goto? But, Is the goto-less solution the easiest to read and understand?
With the invention of catchable exceptions and break-label, most of the remaining cases where a goto was useful have evaporated. I've had very few cases in Java where I ever had any desire to write a goto. But there are a few. Yes, I can always get around them by setting flags, moving code into functions, and/or writing huge, deeply-nested IF statements. But sometimes those things suck bigger than goto's.
Admin
Um, NPE is a RuntimeException - this code won't even work
Admin
When our programming practical started, the lecturer threatened to let anybody fail the course who would use goto.
Admin
Response.Redirect(MyPage.aspx, FALSE);
Wont throw the ugly exception inside try catch
Admin
Umm... ok. I'm maintaining some code that does just this (except it's C++ code, not C). Let me introduce you to a little error, I like to call the "jump to label" error:
Resulting error message (using g++) "error: jump to label 'end' error: crosses initialization of 'vector<string>::iterator begin'
FAIL.
I've give you that gotos might have some use... in really obscure situations. But overall, it makes for a maintainability nightmare.
Admin
Heh, it's rare where I need to have a pointless try block, but for some reason in some legacy COM objects within .NET, even though the COM object itself processes everything ok (so it appears), an exception still bubbles up and needs to happen, so you get code that looks like this (forgive me I'm bad at notepad coding):
Dim a AS New LegacyComObject
Try
a.ExecuteComMethod()
'Why does this code generate this exception even though the method executed just fine and produced the result, very well, just skooshing the error and moving on Catch Ex as COMException
'Doing nothing
End Try
Admin
Admin
When porting a C++ app to Java, I ended up using the following happy construct more than once:
I tried to avoid this as much as possible because it can kill performance, but there were quite a few gotos around.
Admin
Admin
IMO the correct way to decide when to use exceptions and when not to is not by looking at "expected vs. unexpected behaviour", it's by "local vs. global handling". Exceptions have the unique property of propagating up the stack and thereby allowing you to write global, generic error handling code without having to call it explicitly, and to override it with more specific error handling code where necessary.
This means the code is a WTF not because it uses exceptions to do something non-exceptional, but because it uses exceptions for local flow control within a method.
Of course, both criteria correlate - global, generic error handling is pretty much the only thing you can do about completely unexpected stuff.
Admin
Admin
FYI: GOTOs suffer same problems as guns. Sure they themselves don't kill programs, just as guns themselves don't kill people, but controlling how and when to use them is a major issue, and in most cases better solutions exist but are unused because of the blind use of goto/guns. And by the time that is figured out its too late and you have spaghetti code/massacre.
Admin
I'm fed up of the claim that "you shouldn't use exceptions for control flow because exceptions are supposed to be exceptional". That's like saying "you shouldn't use read-only variables because variables are supposed to be variable".
That which we call a variable by any other name would still be a name bound to a value that might or might not be mutable. And that which we call an exception by any other name would still be a structured, highly-constrained form of goto with the ability to propogate arbitrary data up the call stack to the first relevant handler.
Look at what a construct does and how it affects code maintainability, not what English words its name resembles.
Admin
Um, at least in Java "RuntimeException extends Exception" - therefore "Exception" is the most generic of the user-catchable exception types, so this is a catch-all and does definitely work.
The most generic type in the whole exception hierarchy is "Throwable", which is the superclass of "Exception" and "Error" - the latter demarcates all conditions which are not user-catchable (though some of them can technically be caught, but it is not advisable to do so: "An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch." - from the JSE 5 API docs)
Admin
Unless you can honestly answer "Yes" to all three questions: [image]
Admin
Well that was a pretty weak response, as others have noted...
But if you think having an idea for a different use for a tool renders one unfit to program you should probably head back to ITT... of course that you didn't quote the second half indicates that this is just a troll.
Shit, I am responding to a troll, and not a bright one at that.
Admin
and
Perhaps this has (or rather had) a point in older procedural languages, where functions tended to have hundreds of LOC (whether this was good practice there is still debatable though...)
But in OO such monsters of LOC ;o) are definitely bad practice and a design flaw. If a method body fits on one screen most of the time, I do not see a problem in using more than one exit point (i.e. "return" statement).
This is IMHO much better than resorting to complex conditionals ("if/else") to achieve the same effect - or even worse, coming up with perverted abominations like the original WTF or the one I was showing in my first post.
It might well be that such coding standards lead to such insane constructs in the first place, because the coder can not come up with an implementation that avoids return statements in the middle of the method body without the use of "goto" - so he creates his own "goto" by misusing other language constructs.
Admin
Umm, no. It's just C++ that sucks ;) Seriously though, the OP used C where the idiom is fairly popular (see the Linux kernel source) and is a sort of hand-coded RAII. I actually see nothing wrong with it and use it myself.
And yes, I also use exceptions for breaking out of 10 functions deep when rendering an HTTP response. So there.
Admin
Actually, english is not very consistent in that regard. The original forms are "paradigma" (lat.) / "paradeigma" (gr.) and "dogma" (lat./gr.), but the "a" ending was only dropped in "paradigm".
The word "paradigm" was obviously assimilated earlier and more thoroughly, which is also evident from the plurals: I've only ever seen "paradigms" (never the greek "paradigmata") in english, but for dogma, both forms exist ("dogmas" and "dogmata").
In german on the other hand, paradigm is used in the original greek form "Paradigma" and both plural forms exist, the germanised "Paradigmen" or "Paradigmas", and the greek "Paradigmata" (which is in a way considered more academic).
The very same holds true for "Dogma" (pl. "Dogmen" or "Dogmas" and "Dogmata").
Admin
We have reinvented goto over and over such that we may stop using goto. But, if all you got was goto and used it with a brain then it is no more evil than the constructs which have since replaced it.
But, let's see what they are:
Exceptions; break the flow of the code too, do you get them? Goto exeception_block and catch (exception) look a lot alike. The only difference is one propogates up the stack. Of course, the benefit of this is that we get to play a nice game of "who is really going to catch that exception". Who knows, who cares, some one will...maybe...or maybe the app will die.... Whatever...no big deal. By the time it gets back to the handler, though, what state was the app in when it got thrown? How many stack levels did we skip on through before we got it? I dunno...who cares, doesn't matter. Of course, half those questions you don't have to ask if you use exceptions right...but how many coders do that?
Private functions; yeah, goto fn_name and fn_name() just slay me with their differences. The only large difference is I can rescope all the variables I need in the function. At least that constrains what part of the local stack the "goto" private function can touch.
Loop break/continue; well at least we have named loops and the ability to specify which one we want to break or continue...oh wait, that's...goto! Restricted, obviously, to the bottom/top of a loop.
Nested if/else, additional state variables, etc; yeah, much better solutions. I like making sure the flow of my code is controlled with constructs having a McCabe complexity that reachs the far end of a 32 bit integer. Even better to thrown in state variables that say (doThisLater = true) and make sure I test that somewhere outside my if. This is even better when it says (pleaseDoSomething = magic_number) and check it with a case. And, while I do not know if goto could have saved us here, certainly we could have structured the code better?
Point is, spaghetti code is spaghetti code regardless of the constructs you use. If you write spaghetti, you will do it whether or not you have goto to aid you.
P.S. Style debates are always so much fun. Especially when they degenerate to name calling and intarweb arm wrestling.
Can someone please get me some popcorn? I can't wait for the real show to begin. It may even be as good as that Stalone movie...what was it..."Over the Top?"
Admin
Absoultely not. This attitude makes exceptions seem like they're supposed to be used very rarely - so people still use return codes and other half-baked ideas instead of elegant exceptions.
Running to the end of a file is perhaps not 'exceptional' but is much cleaner to deal with. The supposed overhead in dealing with exceptions is, for the vast majority of situations, dwarfed by the extra cost and confusion in writing hacky stupid code.
Aside: Gotos are bad because they allow for multiple ENTIRES to a code block. Exceptions only allow for multiple EXITS.
Admin
The only insult in my words was the one you conjured in your mind. I was complimenting you on what I thought was a slick bit of wordplay. But alas, as you say, it was not, and the mistake was mine in perceiving it to be so.
Admin
Point 2) WHAT? I can enter an exception block from anywhere (even outside the current stack frame) that a throw occurs. If that's not more than one entry into the exception block, I don't know what is. Hell, that is like a long jump. It does, however, have a single exit off the end of the exception handler unless you rethrow and start the mess again.
Aside:
Do we like things like:
try { obj.fn_that_may_not_succeed(arg1, ...); } catch { ... any exception that the fn may throw. }
try { obj.another_fn_that_may_not_succeed(arg1, ...); } catch { .. etc }
over and over? Because that looks a lot like:
if ((failure_code = obj.fn_that_may_not_succeed) != success) { /* check failure_code and handle */ }
with just a little more state that comes along for the ride with the exception. And, while this state is certainly nice to have, the code still conveys the same logical concept.
Admin
Seriously, this isn't a big WTF. I work with legacy exception handling code that does conditional string checks on the exception message (e.getMessage().startsWith("blah")) to decide how to handle the exception. Hannes should come back when he learns pf the true pain of badly used and abused exceptions.
Admin
So why not just wrap that in a function rather than use gotos? I'm really not trying to be argumentative, I want to know what you think about doing something like this:
Then just calling that instead of the goto. Sure, it's one extra line of code that says:
but to me that's far more readable and way easier to maintain than the previous example using goto. Adding more variables can be "harder" than just using goto but the end results are worth it in my opinion. If you really hate adding more params, just use a struct.
Of course, the real way would be to use RAII with exceptions but sometimes you're stuck looking at the abomination of code that I'm currently trying to figure out. Or you're using straight C.
Admin
Oh and I should say that adding that "return;" there might be against some people's religion/coding standards but I've never had a hard time with functions that have multiple exit points. It could be argued that they are evil but that's not the discussion I'm going for right now :)
Admin
Wow, the performance of that webapp must be awesome: every time the user requests a new page an exception is thrown, which then has to be caught and GC'd! Apparently, the guy who wrote that code doesn't know about using string variables...
If I ever find someone who writes code like that, I will beat them to death with a .NET reference book. (Those things are heavy, y'know.)
Aside:
I work for a programming house that is moving from Delphi/Object Pascal (insert sound of puking) to .NET, and one of the coding standards was "thou shalt not use return in multiple places in a method".
Thankfully, the guys in charge aren't morons and after I provided some examples of how using return early can make code easier and more logical to read, they agreed to change the standard :D.
Admin
This is why we should all be using call/cc.
Admin
GOTOs are alright. if you use a FlowChart. Add a noodle. and Jam IT.
Admin
For me the most compelling reason not use exceptions for flow control (at least in python) is that It is slower, and I have done the profiling to prove it.
I used it a fair bit in code which turned out to be cpu intensive, so we came to the profiling stage. replacing try ... except blocks with if ... else blocks was the single largest speedup we managed to achieve, anything else would have required moving logic from python to C.
Admin
Whay, haven't you heard of the DRY principle? He doesn't repeat the redirection code that way!
Admin
This is why I hate goto's - bad programmers see them and think can and should be used in places where other constructs would work perfectly.
My current employer has a ton of legacy vb and asp/vbscript code written either by bad programmers in the past, or by current Indian programmers (I assume there are good programmers over there, but my company doesn't seek them out, if it could even recognize them if it tried). Either way I've seen goto's abused all over the place, and I assume if they could use exceptions they would abuse them as well.
Recently someone asked me to help bring them up to speed with .Net, and I remember specifically telling them "If you use exceptions to handle logical conditions I will submit your code to TDWTF" :)
Admin
The goto function was made for procedural programming. With the advent of object oriented and event driven programming, there is no need for the goto statement. Then again, some would say writing a procedural program in C# is pure evil. But I do write small 'scripts' in C# from time to time that are completely procedural. As long as you are not abusing the language and your program is efficient, go for it. But, I will never use the goto statement in my C# code.
Admin
Actually, we have users to do that for us.
Admin
Admin
Actually I've used a similar pattern myself on a few occasions. Its not really that bad.
Admin
A while ago I wrote some FastTracker (*.xm) playback routine that seemed to need goto. FastTracker can play back sounds in different modes, one of them being ping-pong. Ping-pong will alternate between forwards and backwards playback, reversing direction between the loop points.
Okay you goto haters, how would you refactor this? (It could ping-pong many thousands of times a second, so recursion is out.) These are the only two gotos in the program.
Admin
The "GOTOs are bad" thing comes from a time when you could GOTO any line in the entire program. I remember people taking advantage of this often (including me).
GOTOs within small procedures are ok I guess. I think x86 CPUs have a range of 128 bytes for a conditional jump. If only there was a way to enforce that at high level...
Admin
Hey, Response.Redirect is the GOTO of the 21st century...
Admin
I am currently ordering a t-shirt to that effect :)
Admin
That's correct but misleading. Redirect(string) always throws ThreadAbortException, no matter whether you're in a try block or not (how would ASP.NET even know you're using a try block, and why should it care?). This is not a problem, it's by design. The problem is that many programs use a "catch (Exception ex)" in conjunction with this try, and the given handler then does things that are inappropriate for the ThreadAbortException thrown by Redirect. So one easy solution is to check whether the caught exception is a ThreadAbortException, and if so, rethrow it without any further processing. Alternatively, if you just do nothing in the handler, .NET will automatically rethrow the exception for you. As a side note, the correct way to rethrow the exception "ex" from inside the handler that caught it is "throw;", not "throw ex;", dear naughty stack trace smashers.
We now have two possible solutions to the above-mentioned problem, both of which make more sense than throwing the custom exception seen in the CodeSOD.
Admin
The code used as a counter-example to the popular argument "GoTos are evil" contains lots of return statements which is just even more horrible than a "basic GoTo usage".
So yes, in this case GoTos look better then millions of return statements... So What ?
Admin
I must confess I am happy with using goto. I mean when writnig embedded code with only a main(), why not use a goto? It's efficient and effective.
As with all things everything has it's place and shouldn't be ruled out!
Admin
Goto is used quite frequently in the Linux kernel, because it allows very clean, readable code if you have to cleanup (locks, memory, ...) after an error. See this discussion on the kernel mailing list, where you can find the following excellent example:
Admin
And of course, passing return codes up the stack is a pain in the ass, whereas exceptions propagate up the stack automatically.
Admin
CPUs don't have any understand of 'classes' or scripting languages, yet we still use them for development.
Admin
Actually, that's how you performed exception handling in classic ASP (VBScript): You use "On Error Resume Next" prior to a statement that could generate an exception, then check the global Err object for errors. So something like:
Is akin to this in a "better" language:
It's just more primitive and limited (and convoluted). The surprising thing is that so many people just used "On Error Resume Next" to absolutely ignore the error. That's not only bad practice, that's just plain stupidity and ignorance.
Admin
Or, an easier (and may I say, better) solution is to send "False" as the second argument to Response.Redirect() which will prevent the thread from being aborted, and code properly your exit path.