Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 14:37 26 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Memory issues

Author Message
karlelch

Senior Member

Joined: 30/10/2014
Location: Germany
Posts: 172
Posted: 07:35pm 03 Feb 2024
Copy link to clipboard 
Print this post

Hi,

I am getting the `Too many global variables` error and to solve that, I am wondering what counts as global variable? Identifiers declared with `Dim` and `Const` only? Or also `Static`?

Thanks!

Memory after the error:
Program:
 49K (36%) Program (1672 lines)
 83K (64%) Free

Library:
  3K ( 2%) Library
129K (98%) Free

Saved Variables:
 16K (100%) Free

RAM:
 40K (24%) 272 Variables
  5K ( 2%) General
115K (74%) Free


My options:
PicoMite MMBasic Version 5.08.00
OPTION AUTORUN  ON
OPTION LIBRARY_FLASH_SIZE  21000
OPTION COLOURCODE ON
OPTION HEARTBEAT OFF
OPTION CPUSPEED  252000 'KHz
OPTION DISPLAY 64, 80
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6787
Posted: 08:57pm 03 Feb 2024
Copy link to clipboard 
Print this post

AFAIK all variables are global unless used as local. So, in a SUB:

SUB something  '(you can do the same in a FUNCTION)
LOCAL a,b,c$
STATIC d
e = 5
...
END SUB

a,b and c$ are created with null values at the start of the sub and destroyed on leaving it. d is also created on first entering the SUB or FUNCTION but it's value is retained and is reloaded next time the SUB or FUNCTION is re-entered. It isn't a global variable and isn't available outside the sub or function. I assume it is stored in the variables area though. e is a global variable and it's value is changed.

If you had used DIM or CONST to create a, b and c$ at the beginning of the program then those are global and are not affected by the LOCAL ones.

Global variables exist until the program ends or CLEAR is used to get rid of them, or ERASE is used to get rid of arrays.

Local variables are always transitory. It slows the program a little while they are created and destroyed, but it's a very efficient way to use the variable space.
Edited 2024-02-04 06:59 by Mixtel90
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2135
Posted: 09:27pm 03 Feb 2024
Copy link to clipboard 
Print this post

Does a array count as one variable or many?

If it counts as one group related variables in an array.
eg. replace:-
Dim Volts, Amps, Power.factor
With
Dim VAP(2) 'base 0
 
karlelch

Senior Member

Joined: 30/10/2014
Location: Germany
Posts: 172
Posted: 09:40pm 03 Feb 2024
Copy link to clipboard 
Print this post

Thank you for the detailed reply.

Somehow I did not consider the static variables - I guess I thought they were not counted at global, but your explanation makes sense.

I like static variables because they allow subs to “remember”, while being hidden from the global context. But the downside is that the program reaches the total number of global variables only when all subs and functions that use static variables at least once …

In often called subs I sometimes make variables static instead of local to speed things up. But the gain in speed seems mostly marginal.
 
karlelch

Senior Member

Joined: 30/10/2014
Location: Germany
Posts: 172
Posted: 09:46pm 03 Feb 2024
Copy link to clipboard 
Print this post

  phil99 said  Does a array count as one variable or many?

If it counts as one group related variables in an array.
eg. replace:-
Dim Volts, Amps, Power.factor
With
Dim VAP(2) 'base 0

Yes, true. But then good programming style would call for constants to address the elements, e.g., const ID_VOLTS = 0 and VAP(ID_VOLTS) = 5.6, ending up with more global variables/constants then before  
 
flip
Senior Member

Joined: 18/07/2016
Location: Australia
Posts: 114
Posted: 09:49pm 03 Feb 2024
Copy link to clipboard 
Print this post

My 2c worth (not confident as haven't tested recently)

STATIC (as they are permanent) have to occupy space for the life of the program, I guess first time the procedure is called.

I remember for the Micromite and Geoff's MM for Windows(DOS/text), the STATIC modifier prefixes the varname with the procname,(and can be seen globally) which can be useful.(occupies permanent space)...maybe can free up with ERASE {procname}{varname}  ??


I think DIM can be assigned in a procedure, but CONST had some issue when the same one exists in two procedures.

But in any case ERASE can free up variable-namespace. (which makes me wonder does ERASE work with CONSTs...)

Maybe needs testing to prove some of these things?



Regards Phil
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6787
Posted: 09:59pm 03 Feb 2024
Copy link to clipboard 
Print this post

I doubt if there's much difference in speed between LOCAL and STATIC.

For LOCAL:
enter routine
create variable with null value
...
destroy variable
exit

For STATIC:
enter routine
look up name of static variable
load static variable
...
update static variable value
exit

STATIC may even be slower. Not tested this. :)
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
karlelch

Senior Member

Joined: 30/10/2014
Location: Germany
Posts: 172
Posted: 10:06pm 03 Feb 2024
Copy link to clipboard 
Print this post

  flip said  My 2c worth (not confident as haven't tested recently)

STATIC (as they are permanent) have to occupy space for the life of the program, I guess first time the procedure is called.

I remember for the Micromite and Geoff's MM for Windows(DOS/text), the STATIC modifier prefixes the varname with the procname,(and can be seen globally) which can be useful.(occupies permanent space)...maybe can free up with ERASE {procname}{varname}  ??


I think DIM can be assigned in a procedure, but CONST had some issue when the same one exists in two procedures.

But in any case ERASE can free up variable-namespace. (which makes me wonder does ERASE work with CONSTs...)

Maybe needs testing to prove some of these things?

Interesting - thanks for the hint. I’ll have a look.

In my programs I tend to use many constants to make the code readable and adaptable. So a great solution would be constants that ”don’t eat bread”. Like #define in C. But that’s not compatible with the interpreter approach.

Best
Thomas
 
karlelch

Senior Member

Joined: 30/10/2014
Location: Germany
Posts: 172
Posted: 10:10pm 03 Feb 2024
Copy link to clipboard 
Print this post

  Mixtel90 said  I doubt if there's much difference in speed between LOCAL and STATIC.

For LOCAL:
enter routine
create variable with null value
...
destroy variable
exit

For STATIC:
enter routine
look up name of static variable
load static variable
...
update static variable value
exit

STATIC may even be slower. Not tested this. :)

I measured it for a few cases. In my experience, local for arrays seems a bit slower, but as I said, the difference is marginal. Static instead of local for simple variables does not seem to make a difference.
 
flip
Senior Member

Joined: 18/07/2016
Location: Australia
Posts: 114
Posted: 10:41pm 03 Feb 2024
Copy link to clipboard 
Print this post

Sorry got ideas stuck in my head and have to continue probing the edge

Bear in mind all this is using it at boundary cases / dodgily and WILL reduce readability / maintainability, I'm just playing to get understanding what does / does not cause problems..checking a couple of things at once as follows:
CONST foo="Initial Value"
Sub RedefConstInProcDoesntWork 'But ERASE does, also Static Var can become visible
Static Integer Var=1
  ?"Var (in proc)=";var
  ERASE foo
  CONST foo="FOO"
End Sub

? "foo=";foo
'? RedefConstInProcDoesntWorkVar   'if you look at variable BEFORE running procedure, it breaks your procedure, i.e. this is BAD outside USE OF STATIC Var

RedefConstInProcDoesntWork
? "Proc Erases foo but doesn't set to new value, referencing foo returns value of default type:";foo
ERASE foo
CONST foo="foo"
?"foo=";foo

? "Globally visible local var =";RedefConstInProcDoesntWorkVar;" works!"
Output:
foo=Initial Value
Var (in proc)= 1
Proc Erases foo but doesn't set to new value, referencing foo returns value of default type: 0
foo=foo
Globally visible local var = 1 works!

(Geoff's MMBASIC for DOS/Windows (Text-based)
EDIT - In terms of speed I'd have thought that STATIC only defines the variable once, and doesn't need to create/erase every invocation of procedure.But maybe number of variables becomes a slowing factor at runtime

Regards Phil
Edited 2024-02-04 08:52 by flip
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4039
Posted: 12:22am 04 Feb 2024
Copy link to clipboard 
Print this post

IIRC from my work on MMB4L:

- If you use CONST inside a fun/sub then it is local to that fun/sub.

- You cannot declare a global CONST within a fun/sub.

- You can DIM a global variable within a fun/sub.

- Declaring a STATIC within a fun/sub creates both a global with the variable name prefixed by the fun/sub name AND also a local with the un-prefixed variable name. Every time you exit the fun/sub the value of the local is copied into the corresponding global (I'm guessing here). Every time you re-enter the fun/sub that local is again created with the value taken from the corresponding global, hence the "static" behaviour.

  karlelch said  I am wondering what counts as global variable? Identifiers declared with `Dim` and `Const` only? Or also `Static`?


Given the above I believe "globals" are:
 - all DIM variables
 - all CONST declared outside of fun/sub
 - all STATIC variables

Best wishes,

Tom
Edited 2024-02-04 10:26 by thwill
Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6098
Posted: 01:50am 04 Feb 2024
Copy link to clipboard 
Print this post

Why guess
'
DIM var0,var1,var2,var3,var4,var5,var6,var7,var8,var9,var10,var11,var12,var13,var14,var15
DIM var16,var17,var18,var19,var20,var21,var22,var23,var24,var25,var26,var27,var28,var29,var30,var31
DIM var32,var33,var34,var35,var36,var37,var38,var39,var40,var41,var42,var43,var44,var45,var46,var47
DIM var48,var49,var50,var51,var52,var53,var54,var55,var56,var57,var58,var59,var60,var61,var62,var63
DIM var64,var65,var66,var67,var68,var69,var70,var71,var72,var73,var74,var75,var76,var77,var78,var79
DIM var80,var81,var82,var83,var84,var85,var86,var87,var88,var89,var90,var91,var92,var93,var94,var95
DIM var96,var97,var98,var99,var100,var101,var102,var103,var104,var105,var106,var107,var108,var109,var110,var111
DIM var112,var113,var114,var115,var116,var117,var118,var119,var120,var121,var122,var123,var124,var125,var126,var127
DIM var128,var129,var130,var131,var132,var133,var134,var135,var136,var137,var138,var139,var140,var141,var142,var143
DIM var144,var145,var146,var147,var148,var149,var150,var151,var152,var153,var154,var155,var156,var157,var158,var159
DIM var160,var161,var162,var163,var164,var165,var166,var167,var168,var169,var170,var171,var172,var173,var174,var175
DIM var176,var177,var178,var179,var180,var181,var182,var183,var184,var185,var186,var187,var188,var189,var190,var191
DIM var192,var193,var194,var195,var196,var197,var198,var199,var200,var201,var202,var203,var204,var205,var206,var207
DIM var208,var209,var210,var211,var212,var213,var214,var215,var216,var217,var218,var219,var220,var221,var222,var223
DIM var224,var225,var226,var227,var228,var229,var230,var231,var232,var233,var234,var235,var236,var237,var238,var239
DIM var240,var241,var242,var243,var244,var245,var246,var247,var248,var249,var250

MEMORY
testit
MEMORY

SUB testit
LOCAL varx1,varx2,varx3,varx4,varx5, varx6
STATIC Svar1, Svar2 ', Svar3,Svar4
PRINT "sub run"

END SUB


Compare the two MEMORY results.
The static variables get counted after the sub is run.

Remove the comment in the static declarations and run again = error.

edit: sorry about the wordwrap...
Jim
Edited 2024-02-04 11:51 by TassyJim
VK7JH
MMedit   MMBasic Help
 
karlelch

Senior Member

Joined: 30/10/2014
Location: Germany
Posts: 172
Posted: 07:07am 04 Feb 2024
Copy link to clipboard 
Print this post

  TassyJim said  Why guess

So true  

Thanks for all of your input! That was very helpful.
I already managed to change my code to free up some global variable slots.
It was also interesting to learn that statics can be accessed globally ...

Cheers
Thomas
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6787
Posted: 08:19am 04 Feb 2024
Copy link to clipboard 
Print this post

Very interesting. The manual describes STATIC variables as only being visible inside the SUB or FUNCTION, like a LOCAL. Obviously, they have to be stored somewhere so storing them in the variables area with a prefix makes sense.  :)
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024