Variable by reference in procedure

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Demivec
Addict
Addict
Posts: 4267
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Variable by reference in procedure

Post by Demivec »

It would seem that PureBasic already allows returning more than one value from a procedure by the use of pointers as parameters. The process allows the return of structures also.

Code: Select all

Procedure.i test (in$, x.i, *refStr.C:haracter, *outY.Integer, *outStr.String)
  ; procedure code
  *outY\I = 42
  *outStr\s = in$ + ": " + x + " : " Str(*refStr\c)
EndProcedure

;This works. 
test(s$, m.i, @example.s, @newY.i, @newString.String)

;Problems can occur with literals or unstructured string variables (of type .s or $ because
; pointer to structure instead of string contents is needed so string can be modified).
;test(s$, m.i, @"still OK", @600613, @notChangeable.s)
The two problems that remain are pointers to reference literals and getting the pointer to a string structure of a unstructured string variable (of type .s or $). I'll ignore any possible issues with literals because I think these are minor, infrequent or trivial.

The main issue that remains is getting the pointer to the string structure that is used for a string variable declared as either type .s or $. This begs for a new operator, keyword or compiler function. Some such as mk-soft have tried to come up with solutions or suggestions to fix this.

Here are some examples:

Code: Select all

;new operator
*ptrStringStructure = @@some.s ;@@ is the suggested operator

;new keyword
;RefTo is my suggested keyword, I just made this up so I'm sure there are better choices ;)
;it would possibly be limited to being used in a parameter list.
;Other keywords suggested are ByRef or Out.
*ptrStringStructure = RefTo some.s

;or
Procedure.i test (in$, x.i, *refStr.Character, *outY.Integer, RefTo *outStr.String): EndProcedure 
;test(s$, m.i, @"still OK", @600613, @wasNotChangeable.s) 

;or
Procedure.i test (in$, x.i, *refStr.Character, *outY.Integer, *outStr.String):EndProcedure 
;test(s$, m.i, @"still OK", @600613, RefTo wasNotChangeable.s) 

;new compiler function RefTo()
*ptrStringStructure = RefTo(some.s)

;or
Procedure.i test (in$, x.i, *refStr.Character, *outY.Integer, *outStr.String):EndProcedure 
;test(s$, m.i, @"still OK", @600613, RefTo(nowChangeable.s)) 
While the names for the things can be discussed to come to something agreeable, I don't think there is needed any additional possibilities than the ones I enumerated. It is needed for advanced string pointer use inside procedures when a parameter is a common string variable. PureBasic hides these structure details for common use and if really needs a way to unhide these details for advanced use cases.

I don't think it would break anything. I personally favor a new compiler function so it is obvious what is happening and to show it is expressly wanted when passing a parameter.
Last edited by Demivec on Tue May 13, 2025 7:43 am, edited 3 times in total.
AZJIO
Addict
Addict
Posts: 2191
Joined: Sun May 14, 2017 1:48 am

Re: Variable by reference in procedure

Post by AZJIO »

If you use @@some.s, then there is no need to use "RefTo" for "*outStr.String" in the function parameters. We could use "RefTo var.s" to create a structure inside the function, but show it to us as a var variable. Then we wouldn't have to use a structure inside the function.

As for the name, it is better to use the well-known name ByRef.

We could solve such a CopyMemoryString("Hello", @*Pointer) entry here as CopyMemoryString("Hello", @@some.s) so as not to create an intermediate variable.
Post Reply