Regarding Goto (YES I KNOW, DON'T SAY IT.)

Blitz3D Forums/Blitz3D Programming/Regarding Goto (YES I KNOW, DON'T SAY IT.)

Adam Novagen(Posted 2012) [#1]
Before any of you start, I'm well aware of the fact that Goto is considered by almost all programmers to be the taboo command that should never ever ever be used, and that it very easily leads to spaghetti code.

I have, however, been using it in one very tidy and convenient way, as in this example:

For bullet.bullet = Each bullet
    For enemy.enemy = Each enemy
        If BulletHit(bullet,enemy)
            enemy\hp = enemy\hp - bullet\damage
            Delete bullet
            Goto nextbullet
        EndIf
    Next

    For mine.mine = Each mine
        If BulletHit(bullet,mine)
            DetonateMine(mine)
            Delete bullet
            Goto nextbullet
        EndIf
    Next

    MoveBullet(bullet)

    .nextbullet
Next

Now, I'm well aware that I could achieve the same results with the following:

For bullet.bullet = Each bullet
    For enemy.enemy = Each enemy
        If BulletHit(bullet,enemy)
            enemy\hp = enemy\hp - bullet\damage
            Delete bullet
        EndIf
    Next

    If bullet <> Null
        For mine.mine = Each mine
            If BulletHit(bullet,mine)
                DetonateMine(mine)
                Delete bullet
            EndIf
        Next
    EndIf

    If bullet <> Null Then MoveBullet(bullet)

Next

As a matter of taste, I just prefer the use of Goto nextbullet instead of a Null check. My question, however, is this: is Goto computationally slower than the aforementioned Null check? If so, I'll probably do some re-tailoring.


Ross C(Posted 2012) [#2]
Wouldn't an EXIT command free you from the loop?


Adam Novagen(Posted 2012) [#3]
Wouldn't an EXIT command free you from the loop?
Yes. It would also cause the program to miss all the subsequent bullet Types as soon as one collided with something. I don't need to get out of the overall loop, I simply need to avoid the MAV causes by checking for a bullet that no longer exists.

(Oh and this is not a literal working example, it's just a top-of-the-head snippet to show the idea.)


Kryzon(Posted 2012) [#4]
Using a flag is definitely better.

For [...]
	deleteThis.bullet = Null
	If [condition to delete] then deleteThis = bullet


	[...]

	If deleteThis <> Null then Delete deleteThis
Next

Don't worry about the speed; using a Goto or If won't make a difference!
If you want reassurance, profile both cases under extreme conditions.

Last edited 2012


Adam Novagen(Posted 2012) [#5]
Isn't that a bit counter-intuitive and adding even more overhead per loop iteration?

Not to sound churlish, but to be perfectly honest all I'm asking on this occasion is whether a quick use of Goto is faster or slower (codewise) than an If statement to make sure the Type isn't Null.

EDIT: Never mind, Kryzon's edit answered that while I posted. Thanks all.

Oh, and NINJA'D!

Last edited 2012


boomboom(Posted 2012) [#6]
If it works and you're happy with it then you don't need any justification in using it. After all you are the only one maintaining your code.

The only point I will make is that the Goto command is removed from a lot of newer OOP languages, so just be aware of other methods of creating the same outcome so you won't find any of your design patterns not working if you ever change languages.


Adam Novagen(Posted 2012) [#7]
... the Goto command is removed from a lot of newer OOP languages, so just be aware of other methods of creating the same outcome so you won't find any of your design patterns not working if you ever change languages.
A good point. I actually am aware of this now that I'm slowly taking up Java in my (unbelievably limited) spare time, but fortunately they (or at least Java) usually have very suitable alternatives that I'm quite comfortable with.


Yasha(Posted 2012) [#8]
1) Goto is about the fastest command there is (Goto = one jump; If = a comparison, then a jump).

2) In most other languages you would probably want to rework this to use "continue", which for some reason was left out of B3D (tidier than a Goto since the jump target is always strictly defined). Java and all other C-syntax languages do have "continue".

If it works and you're happy with it then you don't need any justification in using it


This.

While it's true that Goto is never technically necessary (discounting performance), most of the warnings about spaghetti code are mainly aimed at inexperienced programmers who would want to use Goto or Gosub in place of real procedures, e.g. the famous Dijkstra article about it was mainly talking about early forms of BASIC where Goto was the only way to simulate procedures and subroutines. Dark memories. If you're fully happy with procedural programming (i.e. functions, which you are), then you won't be likely to even think of making that kind of mess.

Last edited 2012