Page 1 of 1

Procedures that can return structures

Posted: Tue Jun 01, 2004 10:32 pm
by The seperator
I allready know you can solve this problem by using pointers but you
still have to use freememory() each time to save memory.

Posted: Tue Jun 01, 2004 11:43 pm
by VPureBasic
Hi The Separator,

You wrote:
I allready know you can solve this problem by using pointers but you
still have to use freememory() each time to save memory
Maybe You can do it like this too:

Code: Select all

Structure STRUCT
     Argument_01.f
     Argument_02.f
EndStructure


Procedure.l    MathFormula( x.f, y.f )

     DefType.STRUCT ReturnStruct
     
     ; Your Code
     ReturnStruct\Argument_01 = x * y
     ReturnStruct\Argument_02 = y / x
     
     ProcedureReturn @ReturnStruct
     
EndProcedure


*Result.STRUCT = MathFormula( 5.0, 10.2 )

ABC.f = *Result\Argument_01
CBA.f = *Result\Argument_02
Hope this will help

Roger

Posted: Wed Jun 02, 2004 12:54 am
by Doobrey
It`s better to create the structure outside of a procedure, as PB will clean up after itself when the procedure ends, and any variables or structures created within it go off to meet their maker..

Code: Select all

Structure STRUCT
     Argument_01.f
     Argument_02.f
EndStructure


Procedure.l    MathFormula( x.f, y.f ,*ReturnStruct.STRUCT)

     ; Your Code
     ReturnStruct\Argument_01 = x * y
     ReturnStruct\Argument_02 = y / x
     
    ;## You could return a value here too, indicating success of failure.
     
EndProcedure

  Result.STRUCT
  MathFormula( 5.0, 10.2,@Result )

ABC.f = Result\Argument_01
CBA.f = Result\Argument_02

Posted: Wed Jun 02, 2004 4:05 am
by VPureBasic
Hi Doobrey,

You write:
It`s better to create the structure outside of a procedure...
Your are right!

Do not takes did badly... Your code looks good... but "The Separator" asked for:
Procedure that will return a structure... :wink:


Roger

Posted: Wed Jun 02, 2004 12:51 pm
by The seperator
Indeed what i mean is you can write something like:

Code: Select all

Structure STRUCT 
     Argument_01.f 
     Argument_02.f 
EndStructure 


Procedure.STRUCT MathFormula( x.f, y.f ) 

     DefType.STRUCT ReturnStruct 
      
     ; Your Code 
     ReturnStruct\Argument_01 = x * y 
     ReturnStruct\Argument_02 = y / x 
      
     ProcedureReturn ReturnStruct 
      
EndProcedure 


Result.STRUCT = MathFormula( 5.0, 10.2 ) 

ABC.f = Result\Argument_01 
CBA.f = Result\Argument_02 
It's just that in some cases it would be easier to directly return user defiened types.

Posted: Wed Jun 02, 2004 9:13 pm
by POedBoy
This would be *very* nice.

Posted: Wed Jun 02, 2004 11:35 pm
by VPureBasic
Hi The Separator,

The only way that you can do it in PB as your looking for is the way Doobrey write his code... PB can't return more than 1 value for answer. That's why you should add your answer address structure as a parameter.

This should looks like this:

Code: Select all

Structure STRUCT 
     Argument_01.f 
     Argument_02.f 
EndStructure 

Global Result.STRUCT

Procedure MathFormula( x.f, y.f, *ReturnStruct.STRUCT ) 
     ; Your Code 
     *ReturnStruct\Argument_01 = x * y 
     *ReturnStruct\Argument_02 = y / x 
     ;      
EndProcedure 


MathFormula( 5.0, 10.2, @Result ) 

ABC.f = Result\Argument_01 
CBA.f = Result\Argument_02 
 
I hope this will help...

Roger

Posted: Thu Jun 03, 2004 3:14 pm
by The seperator
I allready know this, It's just a request for future releases. :)

Posted: Thu Jun 03, 2004 7:09 pm
by oldefoxx
The general rule for procedures in every language is that you can pass a large number of parameters to a procedure, which are placed on the stack by the compiler before calling the procedure, but you can only return one value when you exit the procedure, which is normally in the AX register for 16-bit values, or the combined DX,AX registers when returning 32 bit values. The compiler then performs whatever action is required with the returned value.

So every returned type has to be limited to 16 or 32 bit values. Meaning structures and strings are returned as pointers. The compiler has to remove all the passed parameters from the stack when the procedure is existed, because failure to do this will cause the stack to grow and grow until its capacity is exceeded. I've been told that the C language leaves it to the coder to remember to do this, which would be a royal pain.

Point is, to change the manner in which PureBasic returns information from a procedure is likely to make it unsuitable for creating libraries that can be called from other languages. It's taken many years to work out the bugs of having one language take advantage of another for specific needs, and here you are proposing to make PureBasic incompatable with a standard that has given us that ability.

Posted: Thu Jun 03, 2004 11:22 pm
by Froggerprogger
don't forget the st0-register for floats.
sorry I'm drunken and just wanny type some stuff 8)

... to say something- nonnonnonnonsense: PB could translate during compilation something like:

Code: Select all

Procedure.MYSTRUCT myproc()
  ProcedureReturn bla.MYSTRUCT
EndProcedure
a = myproc
to a consistent code such as:

Code: Select all

Procedure.l myproc()
  bla = AllocateMemory(SizeOf(MYSTRUCT))
  ProcedureReturn bla
EndProcedure
a = myproc
So what I mean is, PB could do the trick for us.

(Though it would be a little bit strange to allocate global memory for the result-structure, because it had to be protected on the first look, but it had to be global to keep it's elements after procedure's end. Hmmm. I still prefer the common and clear "structure-pointer as parameter"-version.)