No announcement yet.

Mainly for Lance but.....

  • Filter
  • Time
  • Show
Clear All
new posts

  • Mainly for Lance but.....

    In a post on the PB/CC forum you explained the purpose of BYVAL
    by stating:

    Now when a string is passed to that SUB, the content of the
    string is passed, not the original variable, so any changes to
    X$ within the SUB are not reflected back to the calling code.
    Wondering if this works in PB/DOS and being the flexable
    programmer that I am, I made up the small test program as
    	$lib all off
            color 14,1
            m$ = "Now is the time"
    	locate 1,1 : print;m$;
            call mysub(m$)
            locate 3,1 : print;m$;
    sub mysub(byval m$)
    	m$ = "The quick brown fox"
            locate 2,1 : print;m$;
            end sub
    and come to find out, it works.

    My question is this: Why would you need a statement like this?

    The purpose of passing a variable and/or the contents of a
    variable is to do something with it. Either change its contents
    or use it to process other data.

    To my way of thinking, if you don't want the contents of a
    variable altered, don't.

    There are no atheists in a fox hole or the morning of a math test.
    If my flag offends you, I'll help you pack.

  • #2
    Without the BYVAL, though, you have no immediate way of knowing whether
    the original value is supposed to be modified by the SUB or not.
    Given the BYVAL, you know that it's safe to do anything you want
    with the variable within the SUB.

    Tom Hanlin
    PowerBASIC Staff


    • #3
      Absolutely! Nothing like trying to debug a program only to find that a deeply nested Sub/Function is changing the contents of a parameter variable accidentally!

      While you can choose to write code that does not change BYREF parameters in the called code, it's very sloppy if making such a change will "break" the calling code. In this situation, making the pass BYVAL might save a lot of hassle, especially if someone else has to maintain the code, or you forget the implications of the parameters when you come back to it in 2 years time/

      Therefore, BYVAL parameters can offer a degree of "peace of mind" in terms of the parameters passed from the calling code. Personally, I make heavy use of BYVAL for these exact reasons.

      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      mailto:[email protected]


      • #4
        Another implication of BYVAL is that it suppresses datatype checking. So,

        $DIM ALL
        DIM MyLong AS LONG
            MyLong = -10
            PRINT MyLong
            CALL MySub(MyLong)
        SUB MySub(BYVAL MyParam AS INTEGER)
            PRINT "MySub("; MyParam; ")"
        END SUB
        will work, even though you' re passing a LONG to a sub which expects an INTEGER. Of course, if you remove the BYVAL, a compile-time type mismatch error is rightly issued.

        Furthermore, with BYVAL, if you pass a wrong value to the procedure - for example, you have SUB MySub(BYVAL MyParam AS WORD) and you pass -10 - again no error is issued but the value the procedure receive is obviously not -10 (in this example is 65526, it depends on the datatypes).

        Davide Vecchi
        dos[email protected]


        • #5
          Sorry David, but your conclusions are incorrect.

          Parameter type-checking is only bypassed if you include an explicit BYVAL (or BYCOPY) clause in the <U>calling</U> code. If the <U>called</U> code is declared to expect a parameter BYVAL, then PowerBASIC will do an automatic type conversion for you for that parameter. When overriding the type-checking, it becomes the programmers responsibility to make sure the data that gets passed is of the correct type, etc.

          For example:
          CALL x(BYVAL y%) ' type checking is disabled for that parameter.
          SUB z(BYVAL E??) ' Passed parameters are automatically converted to Word.
          In the case of passing -10 (the PB/DOS numeric literal rules deem it to be an integer) as a parameter to a Sub/Function declared to expect a BYVAL WORD parameter, then the value is passed directly as the bit-pattern of Integer is interchangable with Word.

          In effect, the Sub/Function receives the Word-equivalent of -10%, which is 65526 (and is equivalent to passing "BITS??(-10%)").

          PowerBASIC Support
          mailto:[email protected][email protected]</A>
          mailto:[email protected]


          • #6
            Thanks for the clarification Lance. So, what i thought was a bypassed type-checking, was a type conversion instead...

            However, i just wanted to mean that a difference between using and not using BYVAL is that if you pass a different datatype and don' t use BYVAL, you get a compile-time error telling you that you passed a mismatched parameter, while when you use BYVAL you don' t get any error (because the datatype is automatically converted ).
            This is good if you passed a different datatype intentionally, but has to be kept in mind if you did it erroneously.

            Mmm, even though i don' t use BYVAL at all (to readily catch my frequent mismatched parameters ), i see it' s better if i read more the docs about it...

            Davide Vecchi
            [email protected]