Structure Return Support

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Env
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 27, 2010 3:20 pm
Location: Wales, United Kingdom

Structure Return Support

Post by Env »

Hey again,

A feature I would like to request is more support for returning structures from Procedures....


I know you can return the pointer of an object (variable, list, whatever) and then directly use a pointer from the procedure call, but it would be nice to support something like this;

Code: Select all

; - Dummy Structure -
Structure myStruct
  lValue.l
  fValue.f
EndStructure

Procedure.myStruct myProcedure()
  
  ; - Create Return Variable -
  myReturn.myStruct
  
  ; - Set Some Values -
  myReturn\fValue = 12345.00
  myReturn\lValue = 6789
  
  ; - Return Variable in its defined form -
  ProcedureReturn myReturn
EndProcedure


; - Create Dummy -
dummy.myStruct = myProcedure()

Thanks,


Env
Thanks!
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Re: Structure Return Support

Post by Rescator »

That could lead to major memory leaks for those not careful. (remember, there is no garbage collector in PureBasic)

This is how you should do this to avoid memory leaks with current PureBasic:

Code: Select all

EnableExplicit

; - Dummy Structure -
Structure myStruct
  lValue.l
  fValue.f
EndStructure

Procedure.i myProcedure(*dummy.myStruct)
 
  ; - Set Some Values -
  *dummy\fValue = 12345.00
  *dummy\lValue = 6789
 
  ; - Return Variable in its defined form -
  ProcedureReturn *dummy ;not really necessary, but returning a pointer if ok and #Null if error might be smart.
EndProcedure

; - Create Dummy -

Define dummy.myStruct

If myProcedure(dummy)
 ;Yup, works.
 Debug dummy\fValue
 Debug dummy\lValue
EndIf
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Structure Return Support

Post by Trond »

That could lead to major memory leaks for those not careful. (remember, there is no garbage collector in PureBasic)
Not if the compiler supported it properly. THen it would free the memory after a procedure call unless it was assigned to something. This is what it does when you return floats (except it frees the floating point register, not memory).
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Re: Structure Return Support

Post by Rescator »

Nope! Because in the original post's example the structure is allocated inside the procedure, so as soon as the procedure is done the memory is freed. (currently)
And you can't do it like you do with strings. (currently)
A string returned by a procedure is put in a temporary string buffer, then copied into the string that the coder want to hold the returned string.
There is no way to do this easily as a "returned" structure could be a structure or a pointer to a structure, and the structure itself may have pointers to data as well.

Now taking the original posts example:

Code: Select all

; - Dummy Structure -
Structure myStruct
  lValue.l
  fValue.f
EndStructure

Procedure.myStruct myProcedure()
 
  ; - Create Return Variable -
  myReturn.myStruct
 
  ; - Set Some Values -
  myReturn\fValue = 12345.00
  myReturn\lValue = 6789
 
  ; - Return Variable in its defined form -
  ProcedureReturn myReturn
EndProcedure


; - Create Dummy -
dummy.myStruct = myProcedure()
In this case the compiler could just do a simple strucure copy.
But what if it was this:

Code: Select all

; - Dummy Structure -
Structure myStruct
  lValue.l
  fValue.f
EndStructure

Procedure.myStruct myProcedure()
 
  ; - Create Return Variable -
  myReturn.myStruct
 
  ; - Set Some Values -
  myReturn\fValue = 12345.00
  myReturn\lValue = 6789
 
  ; - Return Variable in its defined form -
  ProcedureReturn myReturn
EndProcedure


; - Create Dummy -
*dummy.myStruct = myProcedure()
Or what is the structure was this:

Code: Select all

; - Dummy Structure -
Structure myStruct
  lValue.l
  fValue.f
  *mem.otherstruct
EndStructure
Obviously it's kinda stupid to return a struct like that,
but this is people we are talking about, you just KNOW somebody will end up doing that.
And restricting the compiler and debugger to spit out warnings will generate the usual "Why can't PureBasic do this? It works fine with this type of structure".

The idea itself isn't bad, it's just that you couldn't pass a normal structure, the returned structure would have to be limited in some way, maybe a ".." structure? I have no idea really how to solve that in a nice practical way.
I'm sure Fred or Freak can point out why it would be a bad idea to allow returning a normal structure just like that, and why returning strings is not really the same thing.

Even MicroSoft passes the return structure as a pointer to a pointer in the function parameter,
except for the cases when you have to free_something() on a returned handle.
I guess one "could" add a FreeReturnStructure() to clean things up, but that's really no different than allocating normally or passing a pre-allocated structure to a function.
Then again Fred is a smart chap so who knows what he might come up with.

I'm just saying that without some form of garbage collection this will be a pain in the ass to implement and it would be restricted to a static structure. (no pointers, no dynamic content, etc.)
Post Reply