News:

Let's find out together what makes a PIC Tick!

Main Menu

GoSub question.

Started by dr-zin, Jul 05, 2022, 06:16 PM

Previous topic - Next topic

dr-zin

Hi, a quick newbie question (even though I'm an oldbie) on the GoSub command.  Does a Subroutine have complete access to the Global variables defined in the main code setup and present in the Main: code block?  Can it access variables not explicitly sent to it in the GoSub command e.g. [xxx,xxx,xxx], AND can it make changes to the vars. that are reflected in the Main: code once it returns?  I had always assumed the answer was "yes", but a quick confirmation would restore some sanity.
P.S.--I am using a 16F877A, so I can't explicitly pass vars. into the routine due to chip limitations.

Any clarification would be appreciated.  Thanks.

Gamboa

Hi dr-zin,
All variables defined outside a Procedure are global and can be modified at any point in the program.
Only variables defined within a procedure are local to that procedure.

Regards,
Gamboa
Long live for you

dr-zin

Nice.  That's as I remembered it.  However, in reading through that section of the Positron documentation, I got confused.  Namely, what is the point of passing exterior (to the subroutine) variables into the subroutine, when it can access them directly?  The routine can generate its own local scope variables to make changes that can't escape back to the main code block (or other routines/procedures).  And, you can pass back a processed value back to the program Main: upon return.  Is passing vars into the routine just to make reading the code easier to read (you see at the GoSub call what will be passed into the routine, and the variable that will be passed back)?  That does make it more obvious what is being processed and what comes back.
Am I close to understanding this, or is there some subtle nuance that escapes me still?  Thanks.

John Drew

A variable defined inside a procedure is local only, a variable defined outside a procedure is global. Procedures are special in another way and that is their code is not created if the procedure is not called. This is a major improvement over the old sub-routines that use Gosub.
Unless you are struggling for memory I always use procedures for ease of reading and the flexibility they bring.
Libraries using procedures are best written using procedures for the reasons above.
John

Stephen Moss

Perhase some clarity is needed as the question
Quote from: dr-zin on Jul 05, 2022, 06:16 PMCan it access variables not explicitly sent to it in the GoSub command e.g. [xxx,xxx,xxx],
suggests there may be some confusion between sub and proceedures. To my knowledge...
Gosub, called with either the old Gosub Label method or the new SubName() with Sub & EndSub:
The standard Gosub cannot be passed any parameters and so can only use global variables, no local variables

Parameter passing Gosubs (now obsolete - should nto be used): You could pass paramaters to them or use global variables

Proceedures, called by Proceedure(parameters, if any) with Proc Name and EndProc:
These can use global variables without passing them and you can also use local variables created within them. I admit I find it a little confusing that you have the option of passing global variables as it does in a way kind of make passing parameters seem a little redundant. Personally, I pass all parameters even if it is a global as I think it is a good habit to get into.
However, if you do not pass the global parameter I beleive the compiler treats it a specific way, whereas as if you do pass it you can choose if it is passed either ByRef or ByVal which determines if the proceedure can alter the passed parameter or not. 

dr-zin

Thanks all for the great info.  The fog is clearing (slightly ;)).  From my old knowledge of BASIC (yes, all CAPS), circa early 1980's, subroutines were designed to perform tasks, not return values or calculations to the main code body.  That activity was the purpose of Functions.  The current incarnations seemed to have purged out Function routines, and usurped the role of passing parameters and returning calculations to subroutines, and now procedures.  This gradual evolution has made it a little tougher for old-timers to understand the morphing of older structures for newer ones.  I opted for subroutines over procedures because I had a rush project for work, and I am more familiar with subroutines (or so I thought).  Cheers.

John Drew

@dr-zin
In Positron Les has rolled Procedures and Functions into one.
Shakespeare said something about a "Rose by any other name shall smell as sweet". Or something like that. He must have been talking about Procedures :)
John

John Lawton

I don't remember their ever being functions in BASIC, but I do remember them from FORTRAN back in the mists of time (late '60s).

Dompie

Oh yessss FORTRAN my starting language in the late '60s. And yes functions were definitely present.

Johan

top204

#9
Many thanks John. I have never seen the point of both functions and procedures in languages, because they both do exactly the same as each other, except a function "must" return a value.

A Positron procedure can return a value if required, but also just act as a wrapped up subroutine with its own variable and label names inside it, with the option of also passing parameters. But they can also use global variables in them so as to save RAM and also to pass or return SFRs (Special Function Registers), which is extremely important in good libraries. Also, any procedures that are not called from within a program are not placed in the program, so true libraries can be created, and not bulk things up with subroutines that are placed, but never used.

Quite a few of the original good BASIC languages had a procedure mechanism of some sort. i.e. Microsoft BASIC, and here in the UK, the BBC computer BASIC, that had the DefProc directive, that created a procedure. Some had "Def" or "Dfn" directives that where, somewhat, the equivalent of a pre-processor $define, that always acts in-line, but they are not true functions. However, in an interpreted language that did not actually matter, because they were always there in the language's code listing, so could not actually be removed if not used.

The Sub-EndSub directives are what I placed in the Positron8 compiler before I added true procedures, and are just a wrapper for standard subroutines, so the code is easier to read and use because a user can see where a subroutine starts and finishes, and the compiler can add RAM bank resets etc because it knows that the Sub label is the start of a subroutine and not just a jump destination from somewhere else in the program. But they are created "in-place", just like a standard subroutine. Unlike procedures that are not "in-place", and get placed after the main code block (if used), so they can be placed anywhere in the program (except from inside another procedure) and do not block its flow.