Hacker News new | ask | show | jobs
by estebank 4209 days ago
The original context of the "GOTO considered harmful" is lost on most of us, as at the time there were large swaths of developers that were trained before structured programming took off, so people were using global variables and GOTOs instead of procedures and functions. GOTO has its place, specially in C.

It is sinful to jump into a different function and pass around information as global state. GOTO as functionality is tangential in this matter.

3 comments

Growing up in the 80s, that's how a lot of books taught us BASIC, because they catered to a lowest-common-denominator implementation. Fortunately, I was using BBC BASIC, with functions, procedures and REPEAT-UNTIL (and later WHILE and CASE), and the BBC-specific books taught structured programming.
On error GOTO next
The empty catch block of BASIC.
For every line of code (just to be pedantic).

I have customers still churning out wads Classic ASP who think On Error Resume Next magically fixes their shabby code. Makes me weep.

> It is sinful to jump into a different function

I've heard of that. It's called "exceptions", right?

I find it kind of amusing when people are afraid of "goto" but not "throw", "break" or "return".

You skipped the "and pass information around as global state" part. It obviously depends on your language, but ideally an Exception object should be a specific class you can choose to catch or re-raise, and it should include a message. None of the calling state should be visible to you.
I give you that I skipped it. I skipped it intentionally to make a bit of hyperbole.

An exception is still essentially a goto that crosses stack frames. There is a whole class of common bugs, you will see a lot of talk of them in the C and C++ communities, where an early return or a throw at an unexpected time leads to resources not being cleaned up. A lot of good coding styles say avoid this stuff, it's dangerous, and they are not without cause. Whereas a goto cleanup block is often a lot more explicit and therefore can lead to more reliable code than a scheme that encourages not sweating details and not expecting failure at every step.

>It is sinful to jump into a different function

So sinful you can't in C

You can do it in GNU C! It's used to write direct-threading interpreters.

https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Labels-as-Values....

They don't intend for label addresses to be gone to outside of the function they are located in. The stack wouldn't be setup to handle them at all.

Sure, you can store them wherever, and do something like " goto *g_greenthreads[ threadno ].lastpos ", but you would call that within the function defining the label, not outside it.

From your own link: > You may not use this mechanism to jump to code in a different function. If you do that, totally unpredictable things will happen. The best way to avoid this is to store the label address only in automatic variables and never pass it as an argument.

I assumed the parent poster meant back before functionality was expressed as functions; i.e. it's sinful to jump from functionality A to functionality B if it's not expressed in terms of packaged functions, and impossible to do so if it is.
With longjmp you can. Your stack will be trashed, though, so any state better be global!