Both function calls and GOTOs or for that matter even any loop or if-else statements jump to a piece of code.
Then why is it that GOTOs are only considered evil and others are not?
Posted on 2004-01-31 12:17:55 by clippy
I think this sums up the answer nicely.

http://en.wikipedia.org/wiki/GOTO
Posted on 2004-01-31 12:30:25 by Mecurius
In short, goto is considered evil because it can lead to hard-to-follow code (aka spaghetti-code).
You rarely need it in regular code, because of all the other, easier-to-understand constructions. Sometimes there's no good alternative though, so goto is the best way out.
Personally I don't think that you should NEVER use goto, but I do agree that you should always try if there is a better way to structure your code, so that a specific goto is not required. However, sometimes NOT using goto will also lead to more complicated code (using extra booleans to indicate the state, and using ifs, or something), so then you are reversing the whole issue, and that's not good either. Some people don't seem to understand the goto-issue and think they should NEVER use goto, that's too extreme.
Posted on 2004-01-31 12:44:08 by Henk-Jan
I find goto most useful when you've got loads of nested loops, and a single exit condition, rather than have "bool break_condition", and lots of "if (break_condition) break;" statements at the end of each loop, a single goto is so much cleaner.

As Henk says, the "never use" is wrong, I suppose it comes from when you are learning...
Until you know why its bad (i.e. in more complex examples than you tend to learn with), you don't need it, and it is bad most of the time! There are so many things that are morally wrong coding-wise that you don't understand until you've read other people's code which does it.

Mirno
Posted on 2004-01-31 15:53:00 by Mirno
I agree with henk and mirno. Stay away from GOTOs (and unnecessary JMPs) while learning, but use them when you must, after you understand the pro's and con's.

I don't have deeply nested loops very often in my code (which is nice), and if I need to break out from one, it's usually because something bad has happened - which is quite a reasonable time to use exceptions. In C++, this ensures me that objects are destructed as they should be, and I can break out of the nesting without any bools and stuff :)
Posted on 2004-01-31 15:58:02 by f0dder
One of the other things to consider is back when Dijkstra was programming, there really wans't such things as a paramter stack and function were all done by simply jumping to the address code. Without a stack to track through and a place to keep return addresses, you can imagine how scary some of the old timey assembley code must be.
Posted on 2004-01-31 16:22:56 by Mecurius
a stack data structure for calling procedures is absolutely NOT needed unless you have recursive code, which doesnt happen THAT often (well, ofcourse it greatly depends... but well) , OR maybe if you have got the same code being run several times at once by several processes, and even then, its not really necessary.

in other cases, it would be enough to have a return pointer for each function you write, stored in its data field.
identically, putting local variable on the stack could be unnecessary if you kept a data field for each function you write. thats the way i would be seeing things, so you dont need no stack at all.

then, if you dont want this to create static data that use mem without need before you actually call the func, you would have to create another managment system that allows new blocks of mem when you call a func... so it would in fact be quite similar... and you couldnt have flat memory model where code and data share the same address space (unless you accept that you instanciate a new code seg each time you do a call, which i would accept)...

and in fact with oop and guis, you somehow need to instanciate many times the same code, even without recursivity... so its not very useable... but its nicer imho.

another thing i never could grasp is the need for stupid messing with bp/sp (mov bp,sp etc) for accessing local variables.
i feel ppl that invented this never used their brain to understand it was absolutely not needed, because the address of your local variables cant change. someone maybe can tell if i m wrong.

maybe this is nonsense... this is how i feel. the proceszsor has hardware design using these stack schemes for calling routines, but i somehow dislike it.i once wanted to make my programs never use the stack(store return addr in some place in the func's data field, then jump without caring), since i have no recursivity (even deep)and no multitasking(dos, all setup by me)

oh well... :)
Posted on 2004-01-31 19:27:34 by HeLLoWorld
Hrm, not using locals for functions... yes, this would work if your function isn't re-entrant at all. This either requires very careful analysis from your part, or (in the case of HLL), *extreme* amounts of processing. Hell, for non-static functions, it can't even be done compile-time.

Then another problem. Your locals probably must use static memory (allocating heap memory for locals sounds a bit slow to me). How else are you going to do this? Have static data allocated for all the 'local' variables at all times? Sounds pretty wasteful to me.


where code and data share the same address space

Code and data already shared the same address space on most modern OSes, at least the 32bit flat ones (on x86 this includes but is not limited to win32, linux, bsd). If you mean share the same memory pages, this is bad - you can't have code page protection then, and I've heard ;) that mixing code and data is bad cache-wise.


another thing i never could grasp is the need for stupid messing with bp/sp (mov bp,sp etc) for accessing local variables.
i feel ppl that invented this never used their brain to understand it was absolutely not needed, because the address of your local variables cant change. someone maybe can tell if i m wrong.

Because push/pop or other stack manipulation inside a proc will change the esp offset. Of course a compiler or smart assembler can handle this. There's also the point that EBP+xx references are generally two bytes shorter than ESP+xx references. And stack frames make debugging and stack unwinding (in case of exceptions) easer.

If you have a smart compiler/linker and an architecture with a *lot* of registers, you can pretty much do without a stack... I still think it's a convenient thing to have, though.
Posted on 2004-01-31 19:40:50 by f0dder
a stack data structure for calling procedures is absolutely NOT needed unless you have recursive code


This is how things work on a PowerPC. It has a link-register that stores the last return-address. You have to push it on stack manually for recursive functions. Args are generally passed through registers, and local vars are generally handled with registers aswell, you have 32 gp and 32 fp registers anyway, plenty for most stuff.

If you have a smart compiler/linker and an architecture with a *lot* of registers, you can pretty much do without a stack... I still think it's a convenient thing to have, though.


You always need a stack for 'something' :)
Just like you'll always need a heap.
On PowerPC and many other modern architectures you do actually have to implement it manually. There are no special reserved registers and/or instructions. Everything is orthogonal to make the hardware as simple and fast as possible. x86 is exactly the opposite.
68k is a bit odd. It has no special instructions, but the a7 register has slightly different behaviour from all others (you can only write word-aligned with it, basically, when using pre-decrement/post-increment addressing). It is usually aliased as the sp-register.
Posted on 2004-01-31 19:51:51 by Henk-Jan
clippy,

Spaghetti code was a leftover from line numbered basic from a very long time ago. Structured loops are fine if they do what you want but can be a pain if you have for example multiple exit conditions within a loop.

It would in fact be very hard to wemulate spaghetti code in any modern language where the scope of labels is defined at a procedure level but keep in mind that even when you use jumps or GOTO in a high level language that often if you can lay your code out to reduce the number of jumps, it usually runs faster.

CALL/RET is specific to procedures but you can make a mess of jumps if you tried hard enough. Just work out what your program needs to do and don't be restricted by fashion, GOTO has its place if you use it properly.

Regards,
http://www.asmcommunity.net/board/cryptmail.php?tauntspiders=in.your.face@nomail.for.you&id=2f46ed9f24413347f14439b64bdc03fd
Posted on 2004-02-01 07:09:26 by hutch--
Hey, you should see some of the algorithms that were shown in flowchart form. Problems that were tree recursive and used backtracking easily took on spaghetti form.

Working directly with goto's (aka jumps or branches), means you are working at the level of a state machine, and one of the primary tools for designing state machines is the state transition diagram. The standard software state diagram is the flowchart. Flowcharting was the old approach.

Code written to follow a flowchart was generally not well-organized, by modern standards. If you lost the flowchart, sometimes the only way to understand the code was to reconstruct the flowchart.

The modern approach is to start with a high level control structure, and then implement the control structure with jumps.

I have seen way too much novice code where someone attempted to avoid (instead of reduce) redundancy in a loop with a jump. They often made the mistake of skipping incrementing code or a bounds check.
Posted on 2004-02-03 01:56:23 by tenkey