Best Practice - Program Loop

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
everest
Posts: 96
Joined: 31 May 2010, 9:01 AM

Best Practice - Program Loop

Post by everest »

My application needs to continuously run through a looping series of sub routines, which right now are invoked in the Main() sub. I've tried two techniques for calling them:

1) I just use the Call Main() at the end of main to call itself. That seems to cause problems, I suspect because it's a looped subroutine call and a stack is getting smashed at some point? (the chip locks up after a few minutes).

2) I've set up a Goto and a point to make the Main sub loop. This works, but doesn't seem like a good coding practice to me.

3) I can set up a Do-Loop that will never break, which causes compiler warning and also doesn't feel right to me.

What's the best way to handle a situation like this?

-Jeff
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Best Practice - Program Loop

Post by dkinzer »

everest wrote:1) I just use the Call Main() at the end of main to call itself.
Clearly, this results in an infinite recursion which will eventually use up all of the stack space.
everest wrote:2) I've set up a Goto and a point to make the Main sub loop.
Generally speaking, you should avoid using GoTo unless there is no other reasonable way to implement a particular behavior.
everest wrote:3) I can set up a Do-Loop that will never break, which causes compiler warning
This is quite common and probably the best solution. You shouldn't be getting a warning unless there is code after the Do-Loop that can never be reached. Consider this code:

Code: Select all

Sub Main()
  Do
    Debug.Print "Hello, world!"
    Call Sleep(1.0)
  Loop
  Call foo()
End Sub

Sub foo()
End Sub
If you compile this you will get a warning about the call to foo() being unreachable. If you then comment out the call, the warning should go away.

Also, if you ever have a situation where a warning is being issued but you need to keep the code as it is, you can suppress the warning in that particular case. Consider this modified example code:

Code: Select all

Sub Main()
  Do
    Debug.Print "Hello, world!"
    Call Sleep(1.0)
  Loop
#pragma warning(push)
#pragma warning(7 : Off)
  Call foo()
#pragma warning(pop)
End Sub

Sub foo()
End Sub
The changes save the current warning control level and then turn off the warning for unreachable code (warning #7). The third pragma statement restores the previous warning control level.

This is described in the ZBasic Language Reference Manual, Controlling Warnings.
- Don Kinzer
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

Upon further reflection, it occurred to me that you might have the Do-Loop in a procedure other than Main() in which case you would be getting warning #8 (subroutine never returns). This warning is automatically suppressed for the Main() task and for any other subroutine used as a task main subroutine.

If that is the case, you can suppress the never-returns warning thusly:

Code: Select all

Sub Main()
  Call foo()
End Sub

#pragma warning(push; 8 : Off)
Sub foo()
  Do
    Debug.Print "Hello, world!"
    Call Sleep(1.0)
  Loop
End Sub
#pragma warning(pop)
- Don Kinzer
everest
Posts: 96
Joined: 31 May 2010, 9:01 AM

Post by everest »

Yea, my loop wasn't in the Main sub, it was in another sub, so I was getting the warning regardless. Thanks for the response and answering my silly questions. . .speaking of which, I've got another one unrelated to this. . .I'll start another thread :)

-Jeff
Post Reply