Possible to return an allocatable array? 
Author Message
 Possible to return an allocatable array?

Quote:




> > > isn't very elegant to allocate an array in one program unit and
> > > deallocate it in another. But I have a C background (does it
> > show?) and
> > > that form of inelegance seems normal to me. :-)

> > I don't know why this is posted to comp.lang.pl1, but in PL/I they
> > are called CONTROLLED, and it is perfectly reasonable to return
> > a CONTROLLED array.   At least as reasonable as in C.

> > Also, this has been a PL/I feature since about 1966.

> > -- glen

> Prove it by giving fellow pliers an example of this CONTROLLED array,

Read the manual.


Mon, 27 Jun 2005 18:30:01 GMT  
 Possible to return an allocatable array?

Quote:

> Read the manual.

Such replies mean only one thing in Robin'ese,  he cant provide a similiar numFromString function with same
functionality
as I translated from the C++  guy's challenge posted in comp.lang.fortran.
-----------------------------------------------------------------------------
module test_1
contains
function numFromString (s,nan,proxy, v)  result (count)
character(*) :: s, nan
real(8) :: proxy
real,allocatable :: v(:)
integer :: i, k, n, count
count = 1
n = len_trim(s)
do k = 1,n
   if (s(k:k) == ',') count = count+1
end do
allocate ( v(count) )
i = 1 ; count = 0
do k = 1,n
   if (s(k:k) == ',' .or. k == n) then
      count = count+1
      read (s(i:k),*,err=1) v(count) ; go to 2
    1  v(count) = proxy    ! use proxy if data error
    2  i = k+1             ! next data field start
   end if
end do
end function
end module

program test
use test_1
real,allocatable :: vec(:)
integer :: count
character(3) :: nan = 'nil'
real(8) :: proxy = -1.

count = numFromString("1.223,nil,22.33,0.08,nil", nan, proxy, vec)
write (*,'(a,i0)') '#items in string = ',count
write (*,'(a,<count>f7.3)') 'vector = ',vec
end program

above outputs:
#items in string = 5
vector =  1.223  -1.000  22.330   0.080  -1.000

.



Tue, 28 Jun 2005 17:14:05 GMT  
 Possible to return an allocatable array?

Date: Wed, 08 Jan 2003 11:41:04 -0800

Quote:

>> I don't know why this is posted to comp.lang.pl1, but in PL/I they
>> are called CONTROLLED, and it is perfectly reasonable to return
>> a CONTROLLED array.   At least as reasonable as in C.

>> Also, this has been a PL/I feature since about 1966.

> In PL/I, user written functions can only return scalars.

Try:

DEFINE STRUCTURE 1 C, 2 D(4,3) FLOAT;
X: PROC (a) RETURNS (TYPE C);
        DCL a fixed;
        DCL E TYPE C;
        ...
        RETURN (E);
   END X;

Quote:
>  The only attributes
> allowed in the RETURNS option or attribute are data attributes and alignment
> attributes.

and the above, and ...


Tue, 28 Jun 2005 19:14:51 GMT  
 Possible to return an allocatable array?

Quote:


>>In PL/I, user written functions can only return scalars.

> Try:

> DEFINE STRUCTURE 1 C, 2 D(4,3) FLOAT;
> X: PROC (a) RETURNS (TYPE C);
>    DCL a fixed;
>    DCL E TYPE C;
>    ...
>    RETURN (E);
>    END X;

>> The only attributes
>>allowed in the RETURNS option or attribute are data attributes and alignment
>>attributes.

> and the above, and ...

By golly you are right.  They seem to have snuck that in when I wasn't looking.
I should have checked the manual before posting.  What I said was certainly true
of the F and Optimizing compilers, but Personal PL/I and the more recent
workstation compliers (and possibly mainframe compilers) now also allow user
defined types (which can include structures which contain arrays) in the returns
option or attribute.  Observe, however, that with user defined types all array
bounds, area sizes, and string lengths must be restricted expressions, i.e.,
compile time constants.  So it still is impossible to directly return an object
of dynamically determined size using the RETURN statement.

I also see in the Personal PL/I Language Reference that BYADDR and BYVALUE
attributes are allowed in the RETURNS option or attribute.  Interesting.



Wed, 29 Jun 2005 14:17:00 GMT  
 Possible to return an allocatable array?
  Observe, however, that with user defined types all array

Quote:
> bounds, area sizes, and string lengths must be restricted expressions, i.e.,
> compile time constants.  So it still is impossible to directly return an object
> of dynamically determined size using the RETURN statement.

Logical.  The calling routine is responsible for providing the storage
for the returned value.  Whie a procedure can return a VARYING string,
etc. the caller still has to know the *maximum* length prior to the
call.  If you want anything else you have to return a pointer to the
data.


Wed, 29 Jun 2005 21:21:59 GMT  
 Possible to return an allocatable array?

Quote:


>   Observe, however, that with user defined types all array

>>bounds, area sizes, and string lengths must be restricted expressions, i.e.,
>>compile time constants.  So it still is impossible to directly return an object
>>of dynamically determined size using the RETURN statement.

> Logical.  The calling routine is responsible for providing the storage
> for the returned value.  Whie a procedure can return a VARYING string,
> etc. the caller still has to know the *maximum* length prior to the
> call.  If you want anything else you have to return a pointer to the
> data.

Absolutely.  I only pointed it out because there are some on this newsgroup who
seem to be in constant search for a way around this fact.


Thu, 30 Jun 2005 06:20:57 GMT  
 Possible to return an allocatable array?

Quote:
> In PL/I, user written functions can only return scalars.

VA PL/I and Enterprise PL/I also support RETURNS of any TYPE - including
structures and unions. Unfortunately, only fixed size arrays can be
incorporated in a typed structure (hopefully this restriction will be
alleviated in some future version).

Quote:
> The storage used to hold the returned value of a function depends on the
> implementation and is either a machine register or a compiler generated
> anonymous variable which as far as I  know is always of the AUTOMATIC
> storage class...

VA PL/I and Enterprise PL/I support byaddr and byref in the RETURNS
attribute. byaddr essentially means that the client supplies an address,
byvalue means that essentially the value is passed back in a register
(pair). How calls are implemented exactly for different calling conventions
on different machines is explained in the platform-specific Programming
Guide.



Quote:

> > I don't know why this is posted to comp.lang.pl1, but in PL/I they
> > are called CONTROLLED, and it is perfectly reasonable to return
> > a CONTROLLED array.   At least as reasonable as in C.

> > Also, this has been a PL/I feature since about 1966.

> In PL/I, user written functions can only return scalars.  The only
attributes
> allowed in the RETURNS option or attribute are data attributes and
alignment
> attributes.  In other words those attributes that characterize a value as
> distinct from the place where the value is stored.  Storage class
attributes
> such as CONTROLLED can only apply to named variables.  The storage used to
hold
> the returned value of a function depends on the implementation and is
either a
> machine register or a compiler generated anonymous variable which as far
as I
> know is always of the AUTOMATIC storage class unless you want to consider
> compiler generated temporaries as a storage class of their own.



Thu, 30 Jun 2005 17:54:38 GMT  
 Possible to return an allocatable array?
Actually, it's not "logical", it's an artefact of the current implementation
by which handles are single addresses, not address pairs, and hence there is
no means of obtaining the referenced type's descriptor. For BASED variables,
there is a concept of REFER, but that works because the declaration is in a
variable context, thus permitting the "initializing" expression to be
addressed in its context. For TYPEs, there would need to be some sort of
type parameterization.

A requirement for such a feature is currently open, but I am not aware of
any planned implementation date.


Quote:

>   Observe, however, that with user defined types all array
> > bounds, area sizes, and string lengths must be restricted expressions,
i.e.,
> > compile time constants.  So it still is impossible to directly return an
object
> > of dynamically determined size using the RETURN statement.

> Logical.  The calling routine is responsible for providing the storage
> for the returned value.  Whie a procedure can return a VARYING string,
> etc. the caller still has to know the *maximum* length prior to the
> call.  If you want anything else you have to return a pointer to the
> data.



Thu, 30 Jun 2005 17:59:57 GMT  
 Possible to return an allocatable array?
While we are discussing PL/I's ability to return aggregates, arrays, and
various interesting objects, I'd like to mention a feature we had in Multics
PL/I. I'm cross-posting alt.os.multics for their benefit as well.

Multics PL/I allowed one to write a procedure that returns (char (*)); i.e.,
an unbounded character string.  Of course, when you got back to the caller,
you either had to assign it to something, or you had to pass it to a
procedure that took a char(*) as a parameter.  In general, the thing to do
was to pass it to a procedure that took char (*) as a parameter, because
that procedure could take its length, allocate some storage somewhere, and
copy it in. Or parse it, or whatever.

I don't recall whether the Multics PL/I compiler allowed you to return a
star-extent array, but there was no particular reason why the char(*) logic
I just described could not also be used for arrays. They are just a little
harder to come by than huge strings.

This was implemented by some fairly straightforward stack manipulation code.
Any needed temporary variable for the character expression was allocated at
the end of the stack frame as usual, and then the return operator popped the
stack frame, extended the stack of the caller to cover the temporary
variable, and then returned.  Said temporary variables were freed at
statement boundaries, so the next statement would pop it off.  Barry Wolman
designed and implemented this logic, and I think he also had it copy the
value up the stack so that there was no wasted space (after all, it might be
a long time before the end of the statement is reached if you are returning
a value that becomes an argument to a call statement).  I think I have this
right. I'm absolutely certain is was Barry, because I can remember him
beaming with pride as he showed me how it worked.

The only restriction was that the returned character string had to fit on
the stack, and the stack was limited to a megabyte. Now this was the mid-70s
to late 80s, and back then, a megabyte of data was a lot of data.  All
segments on Multics were limited to a megabyte, and it didn't seem like a
big deal then.  Only a few programs, such as the database products, went to
the trouble of working around the max segment size limit.

PG



Sun, 03 Jul 2005 07:11:08 GMT  
 Possible to return an allocatable array?
|>
|>Multics PL/I allowed one to write a procedure that returns (char (*)); i.e.,
|>an unbounded character string.  Of course, when you got back to the caller,
|>you either had to assign it to something, or you had to pass it to a
|>procedure that took a char(*) as a parameter.  In general, the thing to do
|>was to pass it to a procedure that took char (*) as a parameter, because
|>that procedure could take its length, allocate some storage somewhere, and
|>copy it in. Or parse it, or whatever.

The VAX PL/I compiler also allows procedures to have a return type of
char(*) or char(*) varying.  As I recall, the implementation was similar
to the one described for the Multics compiler.

--
Jeff Zeeb

"Daddy, my crayon doesn't work.  It needs a new battery" - Matthew (age 2 1/2)
while trying to use a white crayon with white paper.



Sun, 03 Jul 2005 23:20:09 GMT  
 Possible to return an allocatable array?


Quote:
> Multics PL/I allowed one to write a procedure that returns (char
(*)); i.e.,
> an unbounded character string.  Of course, when you got back to the
caller,
> you either had to assign it to something, or you had to pass it to a
> procedure that took a char(*) as a parameter.  In general, the thing
to do
> was to pass it to a procedure that took char (*) as a parameter,
because
> that procedure could take its length, allocate some storage
somewhere, and
> copy it in. Or parse it, or whatever.

And round and round you go.
If PL/I has ability to "allocate some storage somewhere" visible in
callers space
from a routine,  why not do it the original routine?

The example I posted doesnt have ability to allocate function array
declared
allocatable in the caller's space, only to allocate in caller's space
an array PASSED into the function as an allocatable array argument,
and this is a brand new feature thats
in my CVF Fortran as a F95+ feature anticipating the F2K standard..

My last message posted in this topic showing a   Function
numFromString
(that no-one can translate) does exactly this (allocates caller's
array) and passes
its results back to caller,  such that caller program statement
WRITE (*,*) vec      knows #items in vec



Sun, 03 Jul 2005 23:41:41 GMT  
 Possible to return an allocatable array?
Quote:

>And round and round you go.
>If PL/I has ability to "allocate some storage somewhere" visible in
>callers space
>from a routine,  why not do it the original routine?

1. Because the calling program might not have any idea how much data
will be returned.
2. becasue the called program but be another process running on a
different fork, subtask,
    or even on another machine.


Mon, 04 Jul 2005 06:45:22 GMT  
 Possible to return an allocatable array?



Quote:

> >And round and round you go.
> >If PL/I has ability to "allocate some storage somewhere" visible in
> >callers space
> >from a routine,  why not do it the original routine?

> 1. Because the calling program might not have any idea how much data
> will be returned.

not true, as below shows in fortran...

program test
real,allocatable :: widgets(:)  ! allow called routine to decide array
size
call compute(widgets)           ! get #widgets, allocate, load in
array
write (*,*) size(widgets), widgets  ! output #widgets, widget values

Quote:
> 2. becasue the called program but be another process running on a
> different fork, subtask,
>     or even on another machine.

subroutine compute is not contained in another process running on a
different fork, its a called subroutine in program test's process
space,
and ditto for it not being on another machine.. If you want to share
variable widget array with another process, then thats a task thats
now
the responsibility of program test, not its called subroutine, but it
does
have the array (and size)  to share with another process after calling
subroutine compute.


Mon, 04 Jul 2005 14:04:12 GMT  
 Possible to return an allocatable array?


: >   Observe, however, that with user defined types all array
: >
: >>bounds, area sizes, and string lengths must be restricted expressions, i.e.,
: >>compile time constants.  So it still is impossible to directly return an object
: >>of dynamically determined size using the RETURN statement.
: >
<snip>
: Absolutely.  I only pointed it out because there are some on this newsgroup who
: seem to be in constant search for a way around this fact.

Well, what is wrong with the following: declare a BASED structure containing
an array which size is given by other fiels of the structure. Allocate
the structure in the function and return the pointer. The caller then can
use the array as like it was just given by the function. It should work
in F compiler -- as long as I can see the only drawback seem to be lack
of any typechecking. However, using handles (with in newer compiler)
should allow typechecking.

Disclaimer: I have read manuals, but have not tried to code that.

--
                              Waldek Hebisch



Sat, 09 Jul 2005 05:29:54 GMT  
 Possible to return an allocatable array?

Quote:

> Well, what is wrong with the following: declare a BASED structure containing
> an array which size is given by other fiels of the structure. Allocate
> the structure in the function and return the pointer. The caller then can
> use the array as like it was just given by the function. It should work
> in F compiler -- as long as I can see the only drawback seem to be lack
> of any typechecking. However, using handles (with in newer compiler)
> should allow typechecking.

Nothing, that's the way it's done, but someone has to be responsible for
FREEing the structure, and the responsibility has to be clearly
understood by everyone calling the procerdure, or you've just coded a
memory leak.


Sat, 09 Jul 2005 06:17:09 GMT  
 
 [ 40 post ]  Go to page: [1] [2] [3]

 Relevant Pages 
 

 
Powered by phpBB® Forum Software