Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Whats better to SHARED or not
#1
I plan to create a program using many SUB procedures.  Values to change in a sub must be passed or DIM shared.
But which way makes more sense or is more efficient?  Shared it all (variables), shared some variables ?

Questions like these is a big factor to size of program, speed of the program and forgetting to shared a value.
Common sense is out the windows when playing with QB64 code.

Thanks
Reply
#2
Standard's for Good Code always recommend minimizing or eliminating Global variables.

   That being said I find Global variables (Common or Dim Shared) to be useful especially if you want to use a value throughout your code.    But keeping as many variables possible local to subs is also desired.   It's almost a necessity if you want to use any kind of recursion (a sub or function calling itself).   

    I always say do what works.   I personally recommend using Global variables sparingly (a rule I sometimes break myself).   But if it works then it works.
Reply
#3
I would not worry about it, generally speaking there's no real speed difference between the two, definitely not one you're going to notice as it'll be dwarfed by various other details in play and the actual work your SUB does.

Separately, I'd personally recommend staying away from SHARED as much as you can, as avoiding it makes your code easier to reason about as it gets larger.
Reply
#4
If you want to use Subs and Functions in other programs don't Share and don't Const their variables.

I had a routine that used P2 Const for _Pi(2) that I have to fix in every program not setup with that const.
It's really nice to plug-in with Copy/Paste a routine that's already been tested in another program. It saves time for focus on the current program's needs.

Another consideration is that QB64 does not ByVal the varaibles passed through routines, so there is always a risk of accidently unintentionally changing a variables value in calling module. You can also wonder which is better a GoSub or a Routine call without parameters to pass. So if you consider Sharing a bunch of stuff, consider GoSub instead.
b = b + ...
Reply
#5
Sort of what I expected.  Better to ask before tripping over a landmine of problems.  I have fallen for the undeclared shared variable, only to see it as a local to the sub only.  Wondering why nothing happen after the sub call.

Thanks all around.
Reply
#6
(11-07-2024, 05:02 PM)bplus Wrote: If you want to use Subs and Functions in other programs don't Share and don't Const their variables.

I had a routine that used P2 Const for _Pi(2) that I have to fix in every program not setup with that const.
It's really nice to plug-in with Copy/Paste a routine that's already been tested in another program. It saves  time for focus on the current program's needs.

Another consideration is that QB64 does not ByVal the varaibles passed through routines, so there is always a risk of accidently unintentionally changing a variables value in calling  module. You can also wonder which is better a GoSub or a Routine call without parameters to pass. So if you consider Sharing a bunch of stuff, consider GoSub instead.
If I want a variable to retain its value outside of a function's scope, I'll just use a global variable, and declare them all together at the top of the entire program (right after the global Const & Types). This makes it easy to know what global variables are declared, without having to look inside all the functions & procedure to see what's shared. For me that keeps it simpler. 

One thing that bugs me about shared variables inside a routine is, how do you know the function is being called the first time so you know to initialize its value the first time? Seems a little ambiguous. Do you have to declare a second boolean variable called something like bInitialized to track whether the function has been run at least once to know the shared vars have been initialized? Seems messy, so if I'm going to use variables that retain their value, I'll just declare them globally and initialize them all at the start of the program (or if I really want to keep my routines portable, don't use global variables at all, and just pass everything as parameters). 

Also, when declaring a variable as shared inside a routine, is the variable scope unique to that routine? So if I have a function MyFunction1 with a shared variable x%, and another routine MyFunction2 with its own shared x%, are they the same or does each function have its own instance of x%? (If I was at my PC, I could write a test prog and find out, but I am not.) 

I guess if they have their own instance, it could make sense to use shared if the value is only used inside the function, but intuitively it just feels messy, kind of like it's going against some design principle that I'm not remembering. It just seems cleaner to keep retained values either global to the whole program or pass them in parameters (per proper structured programming).

To keep things safe for parameters you just want to send "by value", I just do the simple thing and declare local copies, copy the parameter values to those, and only reference the actual parameter variables if I want to return a new value.
Reply
#7
I don't really understand your problem description, but in general, local variables are preferable to global ones in every respect. In general, but sometimes one can't avoid it.

GoSub is one of those things... The QBasic/QuickBasic reference says that this is only supported for compatibility reasons, but it is not recommended.
Reply
#8
(11-07-2024, 10:08 PM)Kernelpanic Wrote: I don't really understand your problem description, but in general, local variables are preferable to global ones in every respect. In general, but sometimes one can't avoid it.

GoSub is one of those things... The QBasic/QuickBasic reference says that this is only supported for compatibility reasons, but it is not recommended.
Yeah, gosub is one of those hallmarks of spaghetti code that I completely avoid!
Reply
#9
RE: @madscijr longer post above who I am quoting

"If I want a variable to retain its value outside of a function's scope, I'll just use a global variable, and declare them all together at the top of the entire program (right after the global Const & Types). This makes it easy to know what global variables are declared, without having to look inside all the functions & procedure to see what's shared. For me that keeps it simpler."

global variables are Dim Shared at top of code, sure. Also make first letter capital as sign that it is Shared. Just like our Keywords in QB64.

"One thing that bugs me about shared variables inside a routine is, how do you know the function is being called the first time so you know to initialize its value the first time? Seems a little ambiguous. Do you have to declare a second boolean variable called something like bInitialized to track whether the function has been run at least once to know the shared vars have been initialized? Seems messy, so if I'm going to use variables that retain their value, I'll just declare them globally and initialize them all at the start of the program (or if I really want to keep my routines portable, don't use global variables at all, and just pass everything as parameters). "

I use:
Static BeenHere as Long
If BeenHere = 0 then 'never been called yet
' initailize a bunch of stuff also under Static to preserve values inside subroutine
BeenHere = -1 ' no longer a virgin
end if

"Also, when declaring a variable as shared inside a routine, is the variable scope unique to that routine? So if I have a function MyFunction1 with a shared variable x%, and another routine MyFunction2 with its own shared x%, are they the same or does each function have its own instance of x%? (If I was at my PC, I could write a test prog and find out, but I am not.)"

I almost never do that. But according to Wiki it is Shared only with Main not other routines, which I think answers the question you had.

"To keep things safe for parameters you just want to send "by value", I just do the simple thing and declare local copies, copy the parameter values to those, and only reference the actual parameter variables if I want to return a new value."

Yep, that's right. Make copies and alter those values not the calling arguments unless you intend on changing their values.
b = b + ...
Reply
#10
RE: KP
"GoSub is one of those things... The QBasic/QuickBasic reference says that this is only supported for compatibility reasons, but it is not recommended."

GoSub can be very useful for repeated code in main or subroutines, at times it is perfect thing to use.
b = b + ...
Reply




Users browsing this thread: 3 Guest(s)