Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.* 1 > Newsgroup comp.lang.fortran

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 03-25-2012, 04:16 PM
Gary L. Scott
Guest
 
Posts: n/a
Default Derived Type Allocatable Component

Hi,

If I have a sequence derived type with say two allocatable components,
does it matter the order that I allocate the components? Is it
essentially "undefined" until I allocate the final component?
Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 03-25-2012, 04:37 PM
Richard Maine
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

Gary L. Scott <garylscott@sbcglobal.net> wrote:

> If I have a sequence derived type with say two allocatable components,
> does it matter the order that I allocate the components?


No.

> Is it
> essentially "undefined" until I allocate the final component?


Hmm. That's a slightly subtle point, which drove me to check some
details. I'm not sure the standard is 100% consistent on this, though I
didn't spend enough time to be sure of that. The standard does say that
a derived type object is defined if each non-pointer component is
defined. An allocatable is not a pointer (its implementation in memory
might look like one, but that's irrelevant). An unallocated allocatable
is undefined. Thus, that would support your statement above that the
derived-type object is undefined as long as either of the allocatable
components are unallocated.

But you can do intrinsic assignment of a derived type object that has
unallocated components. The standard explicitly describes what happens
in that case (and it is the "obvious" thing - that the variable assigned
to will end up with the corresponding component unallocated).

Hmm. Gotta go. I think I might recall that the requirement fo rthe RHS
of an assignment be defined might not apply to derived types, but I
don't have time to check that. Breakfast call from wife.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
Reply With Quote
  #3 (permalink)  
Old 03-25-2012, 07:13 PM
Gary Scott
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

On 3/25/2012 11:37 AM, Richard Maine wrote:
> Gary L. Scott<garylscott@sbcglobal.net> wrote:
>
>> If I have a sequence derived type with say two allocatable components,
>> does it matter the order that I allocate the components?

>
> No.
>
>> Is it
>> essentially "undefined" until I allocate the final component?


I was wondering because I wanted to use the first two static components
to read a file and assign to them "record type" and number of elements
to be allocated. I guess I should read into static variables and not
make assignment to the DT until after the allocation is complete. (just
trying to reduce # of local variables).

>
> Hmm. That's a slightly subtle point, which drove me to check some
> details. I'm not sure the standard is 100% consistent on this, though I
> didn't spend enough time to be sure of that. The standard does say that
> a derived type object is defined if each non-pointer component is
> defined. An allocatable is not a pointer (its implementation in memory
> might look like one, but that's irrelevant). An unallocated allocatable
> is undefined. Thus, that would support your statement above that the
> derived-type object is undefined as long as either of the allocatable
> components are unallocated.
>
> But you can do intrinsic assignment of a derived type object that has
> unallocated components. The standard explicitly describes what happens
> in that case (and it is the "obvious" thing - that the variable assigned
> to will end up with the corresponding component unallocated).
>
> Hmm. Gotta go. I think I might recall that the requirement fo rthe RHS
> of an assignment be defined might not apply to derived types, but I
> don't have time to check that. Breakfast call from wife.
>


Reply With Quote
  #4 (permalink)  
Old 03-25-2012, 07:14 PM
Gary Scott
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

On 3/25/2012 2:13 PM, Gary Scott wrote:
> On 3/25/2012 11:37 AM, Richard Maine wrote:
>> Gary L. Scott<garylscott@sbcglobal.net> wrote:
>>
>>> If I have a sequence derived type with say two allocatable components,
>>> does it matter the order that I allocate the components?

>>
>> No.
>>
>>> Is it
>>> essentially "undefined" until I allocate the final component?

>
> I was wondering because I wanted to use the first two static components
> to read a file and assign to them "record type" and number of elements
> to be allocated. I guess I should read into static variables and not
> make assignment to the DT until after the allocation is complete. (just
> trying to reduce # of local variables).


It actually appears to be working as designed though...

>
>>
>> Hmm. That's a slightly subtle point, which drove me to check some
>> details. I'm not sure the standard is 100% consistent on this, though I
>> didn't spend enough time to be sure of that. The standard does say that
>> a derived type object is defined if each non-pointer component is
>> defined. An allocatable is not a pointer (its implementation in memory
>> might look like one, but that's irrelevant). An unallocated allocatable
>> is undefined. Thus, that would support your statement above that the
>> derived-type object is undefined as long as either of the allocatable
>> components are unallocated.
>>
>> But you can do intrinsic assignment of a derived type object that has
>> unallocated components. The standard explicitly describes what happens
>> in that case (and it is the "obvious" thing - that the variable assigned
>> to will end up with the corresponding component unallocated).
>>
>> Hmm. Gotta go. I think I might recall that the requirement fo rthe RHS
>> of an assignment be defined might not apply to derived types, but I
>> don't have time to check that. Breakfast call from wife.
>>

>


Reply With Quote
  #5 (permalink)  
Old 03-25-2012, 08:33 PM
Gary Scott
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

On 3/25/2012 2:14 PM, Gary Scott wrote:
> On 3/25/2012 2:13 PM, Gary Scott wrote:
>> On 3/25/2012 11:37 AM, Richard Maine wrote:
>>> Gary L. Scott<garylscott@sbcglobal.net> wrote:
>>>
>>>> If I have a sequence derived type with say two allocatable components,
>>>> does it matter the order that I allocate the components?
>>>
>>> No.
>>>
>>>> Is it
>>>> essentially "undefined" until I allocate the final component?

>>
>> I was wondering because I wanted to use the first two static components
>> to read a file and assign to them "record type" and number of elements
>> to be allocated. I guess I should read into static variables and not
>> make assignment to the DT until after the allocation is complete. (just
>> trying to reduce # of local variables).

>
> It actually appears to be working as designed though...


except for:

Error 1 error #7822: Variables containing ultimate allocatable array
components are forbidden from appearing directly in input/output lists.

Why this restriction if I have previously fully allocated all components
to match the file content?


>
>>
>>>
>>> Hmm. That's a slightly subtle point, which drove me to check some
>>> details. I'm not sure the standard is 100% consistent on this, though I
>>> didn't spend enough time to be sure of that. The standard does say that
>>> a derived type object is defined if each non-pointer component is
>>> defined. An allocatable is not a pointer (its implementation in memory
>>> might look like one, but that's irrelevant). An unallocated allocatable
>>> is undefined. Thus, that would support your statement above that the
>>> derived-type object is undefined as long as either of the allocatable
>>> components are unallocated.
>>>
>>> But you can do intrinsic assignment of a derived type object that has
>>> unallocated components. The standard explicitly describes what happens
>>> in that case (and it is the "obvious" thing - that the variable assigned
>>> to will end up with the corresponding component unallocated).
>>>
>>> Hmm. Gotta go. I think I might recall that the requirement fo rthe RHS
>>> of an assignment be defined might not apply to derived types, but I
>>> don't have time to check that. Breakfast call from wife.
>>>

>>

>


Reply With Quote
  #6 (permalink)  
Old 03-25-2012, 08:48 PM
Gary Scott
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

>>
>> It actually appears to be working as designed though...

>
> except for:
>
> Error 1 error #7822: Variables containing ultimate allocatable array
> components are forbidden from appearing directly in input/output lists.
>
> Why this restriction if I have previously fully allocated all components
> to match the file content?


Further testing: So it appears that I can list each component
individually in the I/O statement, just not as a single object. Does
that make sense? At least it appears that I don't have to massively
redesign...
Reply With Quote
  #7 (permalink)  
Old 03-25-2012, 09:34 PM
Richard Maine
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

Gary Scott <garylscott@sbcglobal.net> wrote:

> >>
> >> It actually appears to be working as designed though...

> >
> > except for:
> >
> > Error 1 error #7822: Variables containing ultimate allocatable array
> > components are forbidden from appearing directly in input/output lists.
> >
> > Why this restriction if I have previously fully allocated all components
> > to match the file content?

>
> Further testing: So it appears that I can list each component
> individually in the I/O statement, just not as a single object. Does
> that make sense? At least it appears that I don't have to massively
> redesign...


Yes, you can do it that way. As for why the prohibition, I'd point to
exactly the distinction between reading the whole derived-type object
versus reading the individual components.

When you read the whole derived-type object directly, what you are
reading would *INCLUDE* the allocation size, at least it would include
that if it were allowed. The allocation status is part of the value
object, so that would be part of what was read. When you read a single
allocatable component, however, you are reading into the contents of
that component, just as if you were reading into an allocatable array
that wasn't a component.

Consider the parallel to what happens for an INTENT(OUT) dummy argument.
If it has an allocatable component, that component gets deallocated on
entry. You can't allocate the component in the calling routine and
expect that allocation to stick in spite of the INTENT(OUT). Again,
that's because the allocation status of allocatable components is part
of the value of the object.

Reading a variable is much like passing it as an actual argument to an
intent(out) dummy. The value is completely determined by whatever is
defined from the file or the subroutine. It doesn't keep parts that
might have been defined before the read or call.

When you directly read an allocated allocatable variable, that's
different because what you are really reading is into the contents, much
like if it were a pointer and you were reading into the target. (In
fact, yes, you can also read into an allocated pointer and that's what
happens; you are reading into the target).

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
Reply With Quote
  #8 (permalink)  
Old 03-26-2012, 12:17 AM
glen herrmannsfeldt
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

Richard Maine <nospam@see.signature> wrote:
> Gary Scott <garylscott@sbcglobal.net> wrote:


(snip)
>> > Error 1 error #7822: Variables containing ultimate allocatable array
>> > components are forbidden from appearing directly in input/output
>> > lists.


>> > Why this restriction if I have previously fully allocated
>> > all components to match the file content?


>> Further testing: So it appears that I can list each component
>> individually in the I/O statement, just not as a single object. Does
>> that make sense? At least it appears that I don't have to massively
>> redesign...


> Yes, you can do it that way. As for why the prohibition, I'd point to
> exactly the distinction between reading the whole derived-type object
> versus reading the individual components.


> When you read the whole derived-type object directly, what you are
> reading would *INCLUDE* the allocation size, at least it would include
> that if it were allowed. The allocation status is part of the value
> object, so that would be part of what was read. When you read a single
> allocatable component, however, you are reading into the contents of
> that component, just as if you were reading into an allocatable array
> that wasn't a component.


I might believe that in the case of UNFORMATTED, but it is less
convincing in the FORMATTED case.

For UNFORMATTED, one might say that the internal representation
includes things like allocation status and size, and that those
should also be read in. That is less obvious for FORMATTED, though.

> Consider the parallel to what happens for an INTENT(OUT) dummy argument.
> If it has an allocatable component, that component gets deallocated on
> entry. You can't allocate the component in the calling routine and
> expect that allocation to stick in spite of the INTENT(OUT). Again,
> that's because the allocation status of allocatable components is part
> of the value of the object.


> Reading a variable is much like passing it as an actual argument to an
> intent(out) dummy. The value is completely determined by whatever is
> defined from the file or the subroutine. It doesn't keep parts that
> might have been defined before the read or call.


The claim above is for I/O lists, and would also seem to include WRITE.

Now, it might be that someone wants to reserve these for future
definition such that the would work. That is, that one could write
out allocatable data, including the allocation status and size,
and later read it back in again. (Most likely as UNFORMATTED.)
If that is the reason, then I probably agree with disallowing
it for now. Otherwise, it would seem that the obvious way of
doing it, the way the OP expected, isn't so bad.

> When you directly read an allocated allocatable variable, that's
> different because what you are really reading is into the contents, much
> like if it were a pointer and you were reading into the target. (In
> fact, yes, you can also read into an allocated pointer and that's what
> happens; you are reading into the target).


-- glen
Reply With Quote
  #9 (permalink)  
Old 03-26-2012, 02:00 AM
Rafik Zurob
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

Hi Gary

Objects of derived type containing allocatable components can't appear in
built-in I/O regardless of definition status. As you found out, you can
just write the individual components instead of the containing structure.
If your compiler supports user-defined derived type I/O, you can specify
your own routine that will be called to do the write operation. Your
routine will most likely have to check the allocation status of each
allocatable component before writing it and also decide what to write if the
component is not allocated. Look up the write(formatted) and
write(unformatted) generic interfaces for more information.

Richard has already answered about the reasons for this constraint.

Regards

Rafik
Visit the Fortran Cafe at http://ibm.com/rational/cafe

"Gary Scott" <garylscott@sbcglobal.net> wrote in message
news:jknveh$af1$1@dont-email.me...
> On 3/25/2012 2:14 PM, Gary Scott wrote:
>> On 3/25/2012 2:13 PM, Gary Scott wrote:
>>> On 3/25/2012 11:37 AM, Richard Maine wrote:
>>>> Gary L. Scott<garylscott@sbcglobal.net> wrote:
>>>>
>>>>> If I have a sequence derived type with say two allocatable components,
>>>>> does it matter the order that I allocate the components?
>>>>
>>>> No.
>>>>
>>>>> Is it
>>>>> essentially "undefined" until I allocate the final component?
>>>
>>> I was wondering because I wanted to use the first two static components
>>> to read a file and assign to them "record type" and number of elements
>>> to be allocated. I guess I should read into static variables and not
>>> make assignment to the DT until after the allocation is complete. (just
>>> trying to reduce # of local variables).

>>
>> It actually appears to be working as designed though...

>
> except for:
>
> Error 1 error #7822: Variables containing ultimate allocatable array
> components are forbidden from appearing directly in input/output lists.
>
> Why this restriction if I have previously fully allocated all components
> to match the file content?
>
>>
>>>
>>>>
>>>> Hmm. That's a slightly subtle point, which drove me to check some
>>>> details. I'm not sure the standard is 100% consistent on this, though I
>>>> didn't spend enough time to be sure of that. The standard does say that
>>>> a derived type object is defined if each non-pointer component is
>>>> defined. An allocatable is not a pointer (its implementation in memory
>>>> might look like one, but that's irrelevant). An unallocated allocatable
>>>> is undefined. Thus, that would support your statement above that the
>>>> derived-type object is undefined as long as either of the allocatable
>>>> components are unallocated.
>>>>
>>>> But you can do intrinsic assignment of a derived type object that has
>>>> unallocated components. The standard explicitly describes what happens
>>>> in that case (and it is the "obvious" thing - that the variable
>>>> assigned
>>>> to will end up with the corresponding component unallocated).
>>>>
>>>> Hmm. Gotta go. I think I might recall that the requirement fo rthe RHS
>>>> of an assignment be defined might not apply to derived types, but I
>>>> don't have time to check that. Breakfast call from wife.
>>>>
>>>

>>

>



Reply With Quote
  #10 (permalink)  
Old 03-26-2012, 02:00 AM
Gary Scott
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

On 3/25/2012 4:34 PM, Richard Maine wrote:
> Gary Scott<garylscott@sbcglobal.net> wrote:
>
>>>>
>>>> It actually appears to be working as designed though...
>>>
>>> except for:
>>>
>>> Error 1 error #7822: Variables containing ultimate allocatable array
>>> components are forbidden from appearing directly in input/output lists.
>>>
>>> Why this restriction if I have previously fully allocated all components
>>> to match the file content?

>>
>> Further testing: So it appears that I can list each component
>> individually in the I/O statement, just not as a single object. Does
>> that make sense? At least it appears that I don't have to massively
>> redesign...

>
> Yes, you can do it that way. As for why the prohibition, I'd point to
> exactly the distinction between reading the whole derived-type object
> versus reading the individual components.
>
> When you read the whole derived-type object directly, what you are
> reading would *INCLUDE* the allocation size, at least it would include
> that if it were allowed. The allocation status is part of the value
> object, so that would be part of what was read. When you read a single
> allocatable component, however, you are reading into the contents of
> that component, just as if you were reading into an allocatable array
> that wasn't a component.
>
> Consider the parallel to what happens for an INTENT(OUT) dummy argument.
> If it has an allocatable component, that component gets deallocated on
> entry. You can't allocate the component in the calling routine and
> expect that allocation to stick in spite of the INTENT(OUT). Again,
> that's because the allocation status of allocatable components is part
> of the value of the object.
>
> Reading a variable is much like passing it as an actual argument to an
> intent(out) dummy. The value is completely determined by whatever is
> defined from the file or the subroutine. It doesn't keep parts that
> might have been defined before the read or call.
>
> When you directly read an allocated allocatable variable, that's
> different because what you are really reading is into the contents, much
> like if it were a pointer and you were reading into the target. (In
> fact, yes, you can also read into an allocated pointer and that's what
> happens; you are reading into the target).
>

Since it may be ambiguous as to what you might want to do in the single
object case, perhaps we could add some sort of syntax modifier (future
standard) that would tell the compiler that you want to treat it as if
you specified the individual components without out having to write the
multiple (possibly a great many) components out explicitly. It would be
nice to be able to do it automatically (including the allocation size)
but I'd rather not be forced to write out huge numbers of components by
name in those cases where it isn't necessary (where I've done the work
to pre-allocate to the correct size).
Reply With Quote
  #11 (permalink)  
Old 03-26-2012, 02:04 AM
Rafik Zurob
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

For some reason, I thought you were trying to write. The reply applies to
read as well, except the generic interfaces are read(formatted) and
read(unformatted).

Regards

Rafik
Visit the Fortran Cafe at http://ibm.com/rational/cafe


Reply With Quote
  #12 (permalink)  
Old 03-26-2012, 02:16 AM
robert.corbett@oracle.com
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

On Mar 25, 9:16*am, "Gary L. Scott" <garylsc...@sbcglobal.net> wrote:
> Hi,
>
> If I have a sequence derived type with say two allocatable components,
> does it matter the order that I allocate the components? *Is it
> essentially "undefined" until I allocate the final component?


An interesting feature of allocatable components is
that circular definitions are allowed. If the type
of a variable includes an allocatable component and
that component has a circular definition that does
not involve pointers, the variable cannot become
defined.

Robert Corbett
Reply With Quote
  #13 (permalink)  
Old 03-26-2012, 02:27 AM
glen herrmannsfeldt
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

Gary Scott <garylscott@sbcglobal.net> wrote:
>>>> Error 1 error #7822: Variables containing ultimate allocatable array
>>>> components are forbidden from appearing directly in input/output lists.


(snip)

> Since it may be ambiguous as to what you might want to do in the single
> object case, perhaps we could add some sort of syntax modifier (future
> standard) that would tell the compiler that you want to treat it as if
> you specified the individual components without out having to write the
> multiple (possibly a great many) components out explicitly. It would be
> nice to be able to do it automatically (including the allocation size)
> but I'd rather not be forced to write out huge numbers of components by
> name in those cases where it isn't necessary (where I've done the work
> to pre-allocate to the correct size).


Especially in the case of list-directed I/O that you might do
when debugging. The whole advantage of list-directed is that you
don't need to write so much to use it. I suppose I wouldn't mind
having the size also printed.

-- glen
Reply With Quote
  #14 (permalink)  
Old 03-26-2012, 02:53 AM
Rafik Zurob
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

Hi

Regarding formatted I/O with objects containing allocatable components:

Allocatables are usually represented using descriptors. A Fortran
descriptor typically contains the address of the data, allocation status,
rank and bounds information (if applicable), and many other vendor-specific
fields. Technically, all fields are vendor-specific since the standard does
not describe or mandate Fortran descriptors, but I'd be surprised if a
vendor didn't have the ones above. The upcoming Technical Specification for
further interoperability with C will specify a "C descriptor" format which
is basically a standard way of describing parts of the Fortran descriptor.

So given this, if you have formatted I/O like this:

type dt
real, allocatable :: a(
real, allocatable :: b(
end type
type(dt) :: x
!...
print *, x

What should the output be if x%a is unallocated? What should it be if both
x%a and x%b are unallocated? If the answer is that we should write nothing
for unallocated allocatable components, then we'll have problems with READ.
If the answer is to write something like "(unallocated)", people will be
unhappy that their formatted data reports contain text about implementation
details.

On input, if we get 20 comma-separated real values on one line, how do we
know how many of these values are part of x%a and how many are part of x%b?
If x%a and x%b were not allocatable, we can tell by looking at the declared
type. But since they're allocatable, the extent can be anything. As
Richard explained, if you have "READ *, x", x%a and x%b will be unallocated
(and if applicable finalized) before the read just like they are with
INTENT(OUT) args. So all this information has to be discernable from the
declared type or the data file we're reading from.

The standard solves this by offloading these decisions to the user. If a
type has allocatable or pointer components, objects of that type can't
appear in an I/O list unless the type has a user-defined derived type I/O
routine. That way, users can write output routines that write things in a
format that can be read by their input routines, if they wish.

Regards

Rafik
Visit the Fortran Cafe at http://ibm.com/rational/cafe/

"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
news:jkocj2$n62$1@speranza.aioe.org...
> Richard Maine <nospam@see.signature> wrote:
>> Gary Scott <garylscott@sbcglobal.net> wrote:

>
> (snip)
>>> > Error 1 error #7822: Variables containing ultimate allocatable array
>>> > components are forbidden from appearing directly in input/output
>>> > lists.

>
>>> > Why this restriction if I have previously fully allocated
>>> > all components to match the file content?

>
>>> Further testing: So it appears that I can list each component
>>> individually in the I/O statement, just not as a single object. Does
>>> that make sense? At least it appears that I don't have to massively
>>> redesign...

>
>> Yes, you can do it that way. As for why the prohibition, I'd point to
>> exactly the distinction between reading the whole derived-type object
>> versus reading the individual components.

>
>> When you read the whole derived-type object directly, what you are
>> reading would *INCLUDE* the allocation size, at least it would include
>> that if it were allowed. The allocation status is part of the value
>> object, so that would be part of what was read. When you read a single
>> allocatable component, however, you are reading into the contents of
>> that component, just as if you were reading into an allocatable array
>> that wasn't a component.

>
> I might believe that in the case of UNFORMATTED, but it is less
> convincing in the FORMATTED case.
>
> For UNFORMATTED, one might say that the internal representation
> includes things like allocation status and size, and that those
> should also be read in. That is less obvious for FORMATTED, though.
>
>> Consider the parallel to what happens for an INTENT(OUT) dummy argument.
>> If it has an allocatable component, that component gets deallocated on
>> entry. You can't allocate the component in the calling routine and
>> expect that allocation to stick in spite of the INTENT(OUT). Again,
>> that's because the allocation status of allocatable components is part
>> of the value of the object.

>
>> Reading a variable is much like passing it as an actual argument to an
>> intent(out) dummy. The value is completely determined by whatever is
>> defined from the file or the subroutine. It doesn't keep parts that
>> might have been defined before the read or call.

>
> The claim above is for I/O lists, and would also seem to include WRITE.
>
> Now, it might be that someone wants to reserve these for future
> definition such that the would work. That is, that one could write
> out allocatable data, including the allocation status and size,
> and later read it back in again. (Most likely as UNFORMATTED.)
> If that is the reason, then I probably agree with disallowing
> it for now. Otherwise, it would seem that the obvious way of
> doing it, the way the OP expected, isn't so bad.
>
>> When you directly read an allocated allocatable variable, that's
>> different because what you are really reading is into the contents, much
>> like if it were a pointer and you were reading into the target. (In
>> fact, yes, you can also read into an allocated pointer and that's what
>> happens; you are reading into the target).

>
> -- glen



Reply With Quote
  #15 (permalink)  
Old 03-26-2012, 04:47 AM
glen herrmannsfeldt
Guest
 
Posts: n/a
Default Re: Derived Type Allocatable Component

Rafik Zurob <nospam@hotmail.com> wrote:

> Regarding formatted I/O with objects containing allocatable components:


> Allocatables are usually represented using descriptors. A Fortran
> descriptor typically contains the address of the data,
> allocation status, rank and bounds information (if applicable),
> and many other vendor-specific fields. Technically, all fields
> are vendor-specific since the standard does not describe or
> mandate Fortran descriptors, but I'd be surprised if a vendor
> didn't have the ones above. The upcoming Technical Specification
> for further interoperability with C will specify a "C descriptor"
> format which is basically a standard way of describing parts of
> the Fortran descriptor.


> So given this, if you have formatted I/O like this:


> type dt
> real, allocatable :: a(
> real, allocatable :: b(
> end type
> type(dt) :: x
> !...
> print *, x


> What should the output be if x%a is unallocated?


Well, one choice is that it isn't allowed.

> What should it be if both x%a and x%b are unallocated?
> If the answer is that we should write nothing for unallocated
> allocatable components, then we'll have problems with READ.


In the case of UNFORMATTED, one would expect that whatever you
wrote could also be read in with the same result.

> If the answer is to write something like "(unallocated)", people
> will be unhappy that their formatted data reports contain text
> about implementation details.


I say that "(unallocated)" isn't an implementation detail.
The bit patterns that indicated it would be, though.

> On input, if we get 20 comma-separated real values on one line,
> how do we know how many of these values are part of x%a and how
> many are part of x%b?


print *,a,b

(a and b are assumed shape arrays) You can't tell from what
is printed how many are a and how many are b.

> If x%a and x%b were not allocatable, we can tell by looking
> at the declared type. But since they're allocatable,
> the extent can be anything.


You also can't tell from assumed shape.

> As Richard explained, if you have "READ *, x", x%a and x%b will
> be unallocated (and if applicable finalized) before the read
> just like they are with INTENT(OUT) args. So all this
> information has to be discernable from the declared type or
> the data file we're reading from.


That is a possible situation, but I don't know that it has to
be that way.

> The standard solves this by offloading these decisions to the user.
> If a type has allocatable or pointer components, objects of that
> type can't appear in an I/O list unless the type has a user-defined
> derived type I/O routine. That way, users can write output routines
> that write things in a format that can be read by their input
> routines, if they wish.


But they can appear without user-defined derived type I/O routines
if they don't have allocatable or pointer components?

-- glen
Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 06:54 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.