Page 1 of 1

Goto within Select/EndSelect

Posted: Tue Dec 08, 2009 10:35 pm
by srod
(Purebasic 4.4 x86).

Hi,

my dodgy memory seems to suggest that this has been discussed before; but I cannot find any related threads just now. I've just spent some time trying to figure out the cause of a crash in a complex bit of code and it turned out to be the use of a Goto statement to cross from one Select/EndSelect construct to another within a procedure. I quite often jump from one Case clause to another within the same Select construct without any problems, but jumping between Selects appears to be a no go area within a procedure.

The same is true (within a procedure) if using Goto within a Case clause to jump outside of the Select/EndSelect code as can be seen with this code (stack corruption) :

Code: Select all

Procedure test(a)
  testVar = 100
  Select a
    Case 1
      Goto L1
  EndSelect
L1:
  Debug "testVar (should = 100) equals " + Str(testVar)  ;Reports incorrect value.
  End  ;Comment this to get a crash!
EndProcedure

test(1)
I know using Goto is 'bad practice', but I nevertheless use it, albeit very sparingly.

Now, looking at the ASM generated by the PB compiler, it is obvious how the above leads to stack corruption since the stack is used as part of the Select statement itself, but what I am asking is whether what I am doing is really unreasonable? I guess I am really wondering why the stack is being used internally in the processing of a Select statement? Would it perhaps not be better to use a register instead?

At the very least, a note in the help manual to the effect that we should avoid using Goto to jump between Select / EndSelect routines etc. would be useful for those spaghetti merchants like myself! :wink:

Re: Goto within Select/EndSelect

Posted: Tue Dec 08, 2009 10:45 pm
by Kaeru Gaman
Image

Re: Goto within Select/EndSelect

Posted: Tue Dec 08, 2009 10:57 pm
by milan1612
(Sorry for being off topic)

Image
by xkcd.com

EDIT:
I also remember a discussion about goto within select blocks, iirc Fred said
something about it being invalid.

But I'm not sure...

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 1:16 am
by Kaeru Gaman
it's just plain clear:
when SELECT uses the Stack, jumping out of a CASE is a stupid idea. period.

furthermore, I can't imagine it is even necessary!

we poor PureBasic programmers are bitten twice: we program in BASIC and PROCEDURAL.
not procedural C, not even ObjectOriented Basic, no, just PROCEDURAL BASIC.
A lot of folks out in the world would not take us serious alone for this.

... now if anybody out there hears that one of us asks "I want to jump forth and back between different cases of different selects".... Image

sorry, srod, you know I love you, but this is breaking my heart...


[edit]
corrected completely misused vocable
[/edit]

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 1:31 am
by netmaestro
You're right about using goto in this way kg, but I think you mean "lurid" :wink:

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 2:09 am
by freak
> I guess I am really wondering why the stack is being used internally in the processing of a Select statement?
> Would it perhaps not be better to use a register instead?

Select statements can be nested so eventually you would run out of registers and have to use stack space anyway. Its simpler this way and it keeps the registers available for expression evaluation.

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 3:21 am
by Kaeru Gaman
@netmaestro
... you're right it was the wrong word... I can't remember wich one I meant, I was thinking about something like the lunatic with toys in the attic...

@freak
now that is a lucid explanation, to use the vocable the right way...

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 8:56 am
by blueznl
Srod is a genius, but sometimes geniusses have to be protected against themselves...

Goto is evil. Kill it.

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 10:12 am
by Foz
Perhaps an early exit keyword, like we have Break for loops would be useful and avoid stack corruption.

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 11:00 am
by srod
@Freak : thanks. I must admit though that I cannot see how nesting necessarily has to lead to using the stack, since when one Case clause is determined to be 'true', the previous incumbent of the register/stack etc. can surely be discarded as it will not be needed again, meaning that it need not reside upon the stack in the first place. Unless I am missing something? :)

@All : regardless of how Goto is regarded, it is a bona-fide part of the PB command set and thus I am free to use it as I wish (within whatever constraints exist anyhow). As already explained, I use it very sparingly and with good reason. All I am really getting at here is that if Goto cannot be used to jump from one Select construct to another then a remark should perhaps be made within the PB user manual.

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 11:15 am
by blueznl
Like I said, you're a genius, but jumping from one select to another one, that is about the worst style of coding I can imagine... <shudder>

Even thinking about such a construction makes my mind hurt!

So, yeah, I understand you want a remark on it, but to me it's unthinkable. Then again, I never claimed to be a good programmer :-)

Re: Goto within Select/EndSelect

Posted: Wed Dec 09, 2009 12:15 pm
by Little John
srod wrote:All I am really getting at here is that if Goto cannot be used to jump from one Select construct to another then a remark should perhaps be made within the PB user manual.
I agree. This would be helpful for using Goto properly.
(I personally never use Goto, but that's not the point here.)

Regards, Little John

Re: Goto within Select/EndSelect

Posted: Thu Dec 10, 2009 7:40 pm
by Marco2007
Hmmm... Goto...I also don`t use it, but maybe that`s the magic of Srod`s fantastic codes :D
When Srod is using Goto: There`s shure an elegant trick with it, and we don`t know this trick...
IIRC Rings is also using Goto sometimes ...

Re: Goto within Select/EndSelect

Posted: Thu Dec 10, 2009 7:44 pm
by srod
No tricks no; just lazy-bastarditus! :wink:

Re: Goto within Select/EndSelect

Posted: Thu Dec 10, 2009 9:51 pm
by idle
couldn't you just pop eax the number or nested levels in the select or add esp nested levels * sizeof(integer)

Code: Select all

 
!pop eax 
goto L1 


Probably not safe Goato(Label,1)

Code: Select all

#sizeInt = SizeOf(integer)
Macro GOATO(merherer,nestlevel) 
    v = nestlevel* #sizeint 
    !add esp,[p.v_v]  
    Goto merherer 
EndMacro 
   
Procedure test(a,b)
  testVar = 100
  Select a
    Case 1
      Select b
         Case 1
           GoaTo(L1,2)
         Case 2
      EndSelect
    Case 2
      Goato(L2,1)
  EndSelect
  ProcedureReturn 1
L1:
  Debug "Goato"
    
  ProcedureReturn 0
L2: 
  ProcedureReturn -1

EndProcedure

Debug test(1,1)
Debug test(2,1)