Menu

The value of variables

jeff
2021-05-13
2021-05-15
  • jeff

    jeff - 2021-05-13

    I have attached the demo program in question and want to know how the value of " HiAddr " is derived.
    Maybe the default value of a variable that is not given a value is zero...

     
  • mkstevo

    mkstevo - 2021-05-13

    HiAddr is a value given to the subroutine as a parameter.

    So.
    If you wanted to write a value of 1,234,567 to EeProm location 0 (zero) you would call the routine like this:

    'PutLEeprom(Value for HiAddr, Value to store in EeProm)
    PutLEeprom( 0,  1234567 )
    'Location "0" (zero) is placed into variable HiAddr.
    'Value 1234567 is placed into Save_Long
    

    This would store the value 1234567 across four byte locations in Eeprom. Those locations being
    Location 0
    Location 1
    Location 2
    and
    Location 3

    For retrieving the value stored in EeProm, you would call the routine like this:

    Let Long_Returned = GetLEeprom(0)
    

    Again the passed value of "0" is placed into HiAddr.
    Long_Returned is then filled with the contents of EeProm locations 0, 1, 2 and 3.

    Hope that makes sense.

     

    Last edit: mkstevo 2021-05-14
  • mkstevo

    mkstevo - 2021-05-13

    I should perhaps point out that the SubRoutine declaration:
    Sub PutLEeprom (HiAddr As Byte, Save_Long As Long)

    Effectively dimensions ("Dim") the variables HiAddr (as a Byte value) and Save_Long (as a Long value).

    In other languages, the variables HiAddr and Save_Long would only exist within the PutLEeprom subroutine and would cease to exist once the sub exits. In GCB basic this doesn't happen and these (and all) variables have global existance, and so are available to the entire program. I try not to use the variables declared this way elsewhere in a program as the values will be overwritten by any call to the subroutine.

    Having had odd effects happen with parameters passed to a subroutine, I now try to declare subroutines with any parameters using the "In" statement:
    Sub PutLEeprom (In HiAddr As Byte, In Save_Long As Long)

    This can prevent variable values passed as a parameter being altered by the subroutine. This only happens very rarely, but using "In" seems to stop it happening at all.

     

    Last edit: mkstevo 2021-05-13
  • mkstevo

    mkstevo - 2021-05-13

    And a final comment...

    The EeProm can only store Byte values. The Long value has to be broken into byte values to store it in EeProm.

    Trying to store a whole "Long" value directly in EeProm will cause it to be truncated to a Byte value.

    Which is why the routine was originally written!

     
  • Jerry Messina

    Jerry Messina - 2021-05-14

    In GCB basic this doesn't happen and these (and all) variables have global existance, and so are available to the entire program

    Is this really true?

    If so, what's the point in "passing parameters"? Why use parameters at all?

     
    • mkstevo

      mkstevo - 2021-05-14

      For me, it simplifies my program and suits my thought process.

      If I call:
      PutLEeprom( 0, 1234567 )

      It is clear to me that the value will be stored in location 0 (and 3,4,5)

      If I then call:
      PutLEeprom( 4, 7654321 )

      It is clear to me that the value will be stored in location 4 (and 5,6,7)

      I also use parameters to call "different" versions of a subroutine. I wrote a subroutine recently for generating some low frequency PWM. I can call this with parameters for frequency, duty cycle and polarity. Again, this allows me to reuse the same subroutine for various situations that might require positive going PWM duties or negative duties.

      Going further, by defining some constants the use of a subroutine call becomes even more obvious:

      Pseudo code follows

      #Define FiftyHz 50
      #Define HundrHz 100
      #Define KiloHz  1000
      #Define FiftyPercent 50
      #Define SixtyPercent 60
      #Define SeventyPercent 70
      #Define PosPWM  0
      #Define NegPWM  1
      
      GeneratePWM(FiftyHz, SixtyPercent, PosPWM)
      GeneratePWM(HundrHz, SeventyPercent, PosPWM)
      GeneratePWM(KiloHz , FiftyPercent, NegPWM)
      
      Sub GeneratePWM(In PWMFrequency As Word, In DutyCycle As Byte, In PWMPolarity As Byte)
          If PWMPolarity > 1 Then
              Let PWMPolarity = 0
          End If
          If DutyCycle < 1 Then 
              Let DutyCycle = 1
          End If
          If DutyCycle > 98 Then 
              Let DutyCycle = 99
          End If
          'Do the PWM generation here
      End Sub
      
       
    • mkstevo

      mkstevo - 2021-05-14

      To some degree, you could omit the parameters totally.

      Let us assume that the function and subroutine for saving and retrieving a long value from EeProm have been written with the sub and variables declared like this:

      Dim HiAddr As Byte
      Dim Save_Long As Long
      
      Sub PutLEeprom
          'Section for storing the parts of a Long value
          'into consecutive bytes in EeProm here
      End Sub
      

      You could then do this:

      Let HiAddr = 0
      Let Save_Long = 1234567
      PutLEeprom
      

      Which is in essence what the original call does when it is called in the first example I gave:

      PutLEeprom( 0, 1234567 )
      

      To my mind, the second example is easier to understand. It looks more obvious to me that the values "0" and "1234567" are related to putting a long value into eeprom.

      That is not to say that either technique is "better" or "worse" than the other, but passing them as parameters is my preferred method, it suits me.

      If you prefer another method that does the same thing, that is fine, what you prefer is right for you.

       
  • Anobium

    Anobium - 2021-05-14

    The answer is memory management and optimisation.

    Great Cow BASIC will share memory locations with many variables when passing items are parameters, and, the optimiser will try to rationalise memory.

    And, it is a good practice - in a sub/function the variable may have a different name to help understanding of the method, whilst using the same memory location as the passed parameter.

     
  • Jerry Messina

    Jerry Messina - 2021-05-14

    Maybe I'm missing something (wouldn't be the first time).

    Doesn't that conflict with what mkstevo said?
    If variables can share memory locations then how can they be global in scope?

     
    • mkstevo

      mkstevo - 2021-05-14

      I was indeed missing something, so will wait for Anobium to expand on his comment:

      Great Cow BASIC will share memory locations with many variables 
      when passing items are parameters, and, the optimiser will try 
      to rationalise memory.
      

      The following suggestions by me turned out to be incorrect. I have left them only to show the context of Jerry's further comments, and my misunderstanding!

      I will (should) let Anobium answer this, as I don't want to put words in his mouth.

      I wonder if he meant that if you call a subroutine with a named variable passed as one of the parameter values the named variable is sometimes used directly rather than copied to the parameter name (which could explain why passing variables to subroutines can sometimes cause them to be corrupted) and a copy of that value used within the subroutine.

      So possibly, in the example below, MyVarAddr and MyVarLong would not be "copied" into HiAddr and SaveLong but actually "be assimilated into" HiAddr and SaveLong, sharing the memory addresses?

      Dim MyVarAddr As Byte
      Dim MyVarLong As Long
      
      Let MyVarAddr = 0
      Let MyVarLong = 1234567
      
      PutLEeprom(MyVarAddr, MyVarLong)
      
      Sub PutLEeprom(HiAddr As Byte, SaveLong As Long)
          'Section for storing the parts of a Long value
          'into consecutive bytes in EeProm here
      End Sub
      

      Although, like you, I could be missing something too!

      Quote by Anobium: There is no assimilation.

       

      Last edit: mkstevo 2021-05-15
      • Jerry Messina

        Jerry Messina - 2021-05-14

        So possibly, in the example below, MyVar_Addr and MyVar_Long would not be "copied" into HiAddr and Save_Long but actually "be assimilated into" HiAddr and Save_Long, sharing the memory addresses?

        Something like that sounds a bit scary to me!

        I agree that the "PutEeprom(param, param)" style is preferable, but if it's just syntactical sugar that's good to know.

        GCB wouldn't be the first compiler to make everything global in nature... just trying to understand the rules. If "local" variables aren't shared then that can have a big impact on total ram usage, but I understand the complexities involved.

        Thanks.

         
        • Anobium

          Anobium - 2021-05-15

          There is no assimilation.

          I am currently travelling away from home on a very serious matter. If you post the code in question again (I cannot find the initial example below). I can look for you.

           
  • stan cartwright

    stan cartwright - 2021-05-14

    ditto. when I dim vars they work in all my program. I know that variables are changed to aliases yo use gcb includes but what us wrong with dim vars at start of code and they work in that code?

     
    • mkstevo

      mkstevo - 2021-05-14

      Because I still think that

      PutLEeprom( 0, 1234567 )
      
      'other code here...
      
      Sub PutLEeprom(HiAddr As Byte, Save_Long As Long)
          'Section for storing the parts of a Long value
          'into consecutive bytes in EeProm here
      End Sub
      

      Is easier to understand than

      Dim HiAddr As Byte
      Dim Save_Long As Long
      
      Let HiAddr = 0
      Let Save_Long = 1234567
      PutLEeprom
      
      'other code here...
      
      Sub PutLEeprom
          'Section for storing the parts of a Long value
          'into consecutive bytes in EeProm here
      End Sub
      

      Horses for courses, but the first example to my eye is more readable and has more flexibility, even more so with the PWM example further up this thread.

      If it were possible to have true "Local" variables with explicit limited scope I would be even happier!

       

      Last edit: mkstevo 2021-05-14
  • stan cartwright

    stan cartwright - 2021-05-14

    I don't know why vars get changed . if I dim var1 as byte why can't it stay like that?

     

    Last edit: stan cartwright 2021-05-14
  • mkstevo

    mkstevo - 2021-05-15

    I'm not sure what you mean Stan?
    Once a variable has been dimensioned its type doesn't normally change?

     
  • stan cartwright

    stan cartwright - 2021-05-15

    But vars are given aliases and I thought they were global through my code but I hear off local variables which makes gcb harder.

     
    • mkstevo

      mkstevo - 2021-05-15

      As far as I am aware there are no local variables in GCB, all are global in scope.

      Aliases are something else again.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.