Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Sourced allocation - how is the value copied?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  9 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Rich Townsend  
View profile  
 More options Jan 31 2011, 5:38 pm
Newsgroups: comp.lang.fortran
From: Rich Townsend <mylastn...@astro.wisc.edu>
Date: Mon, 31 Jan 2011 22:38:08 +0000 (UTC)
Local: Mon, Jan 31 2011 5:38 pm
Subject: Sourced allocation - how is the value copied?
Hi all --

In a sourced allocation of an allocatable polymorphic, how is the
value copied across from the source? For instance, consider this
example, where bar_t is an extension of foo_t:

type(bar_t)               :: b
class(foo_t), allocatable :: f

allocate(f, source=b)

This will allocate f, give it a dynamic type of bar_t, and set its
value equal to b. But how is this value setting done? Is it an
intrinsic assignment? Or, is a defined assignment done (assuming bar_t
has an ASSIGNMENT(=) type-bound procedure)?

If the former, then is it possible to set up f with b's type, but
without any value setting taking place via intrinsic assignment? This
would be useful, for instance, if foo_t and bar_t were linked lists --
for which intrinsic assignment is not the right thing to do.

cheers,

Rich


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
steve  
View profile  
 More options Jan 31 2011, 6:13 pm
Newsgroups: comp.lang.fortran
From: steve <kar...@comcast.net>
Date: Mon, 31 Jan 2011 15:13:44 -0800 (PST)
Local: Mon, Jan 31 2011 6:13 pm
Subject: Re: Sourced allocation - how is the value copied?
On Jan 31, 2:38 pm, Rich Townsend <mylastn...@astro.wisc.edu> wrote:

I believe that that it is an intrinsic assignment.  EBNF
has

SOURCE=source-expr

source-expr           is expr
expr                      is [ expr defined-binary-op ] level-5-expr
defined-binary-op is  . letter [ letter ] ... .

A defined assignment is not a level-5-expr.

--
steve


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Richard Maine  
View profile  
 More options Jan 31 2011, 7:13 pm
Newsgroups: comp.lang.fortran
From: nos...@see.signature (Richard Maine)
Date: Mon, 31 Jan 2011 16:13:21 -0800
Local: Mon, Jan 31 2011 7:13 pm
Subject: Re: Sourced allocation - how is the value copied?

That's pretty much a non-sequitur. You are just talking about the syntax
of the expression. The syntax is, not surprisingly, that of any other
expression. That has nothing to do with what happens after the
expression is evaluated. Defined assignment is not part of the
expression; it is something that might happen with an expression. Heck,
I could generalize your argument to say that there is no such thing as
defined assignment because the syntax of assignment has the same expr on
its right-hand side and "defined asignment is not a level-5-expr."

I don't actually see that the standard uses the word "assignment" at all
in the context of SOURCE= in the allocate statement. It just says that
"the value of allocate-object becomes that of source-expr". (And I see
that f2008 has some different wording - possibly a bug fix, but the
differences have to do only with array vs scalar issues; it still just
talks about "values becoming.") That "value becomes" bit sounds a lot
like the same thing as intrinsic assignment does for cases where the
type and type parameters agree, but I'm not going to go out on a limb
and say that it actually is intrinsic assignment because maybe I've
missed something. I'll waffle and say that it seems to do the same thing
as intrinsic assignment even if it doesn't use that name for it. I
certainly see no justification at all for it being defined assignment.

Sounds to me like what you want is the MOLD= that got added in f2008.
Umm. Anyway I think that is what MOLD= is supposed to do. I sure can't
deduce that from the words of the standard, though. The standard appears
to say nothing at all about what the MOLD= actually does. The complete
and entire description of MOLD, other than just its syntax, appears to
be

"If MOLD= appears and source-expr is a variable, its value need not be
defined."

which I find less than edifying. Even the syntax is confused in that the
restrictions talk about source-expr as though there is only one of them,
even though the BNF shows source-expr in both SOURCE= and MOLD=. I'm
guessing that you aren't supposed to be allowed to specify both SOURCE=
and MOLD=, but I see nothing that quite says that - just words that
don't make much sense if you have both of them. Well, maybe the
"At most one of source-expr and type-spec shall appear" does it, though
my first reading of that was just that you could not specify both
source-expr and type-spec. I suppose maybe it also says that you can't
specify source-expr in two different spots, but I'm sure not impressed
with its clarity.

But even if I grant the syntax as ok, I'm still left completely guessing
as to what the source-expr does when it is in MOLD=. All its description
is in the para that begins with "If SOURCE= appears." I think someone
meant paarts of that to also apply to MOLD=. You just have to figure out
which parts don't make sense if the value might not be defined; that
would be the bit about the "value becoming that of source-expr." I think
that's a pretty good guess, but it would be nice if the standard said
that instead of leaving one to guess.

--
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Rich Townsend  
View profile  
 More options Feb 1 2011, 12:59 am
Newsgroups: comp.lang.fortran
From: Rich Townsend <mylastn...@astro.wisc.edu>
Date: Tue, 1 Feb 2011 05:59:15 +0000 (UTC)
Local: Tues, Feb 1 2011 12:59 am
Subject: Re: Sourced allocation - how is the value copied?

Thanks for the analysis. It seems that MOLD is what I want here -- at least,
going by what is written in John Reid's "The new features of Fortran 2008"
document. Is the standard truly as vague as you say?

cheers,

Rich


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Wolfgang Kilian  
View profile  
 More options Feb 1 2011, 3:21 am
Newsgroups: comp.lang.fortran
From: Wolfgang Kilian <see...@domain.invalid>
Date: Tue, 01 Feb 2011 09:21:29 +0100
Local: Tues, Feb 1 2011 3:21 am
Subject: Re: Sourced allocation - how is the value copied?
On 02/01/2011 06:59 AM, Rich Townsend wrote:

I have a related problem: suppose that there is an allocated array with
polymorphic type, and I want to expand (reallocate) that array.  Here is
some code that realizes the task:

---
module realloc
  implicit none

  type :: base_type
     integer :: i
  contains
    procedure :: assign
    generic :: assignment(=) => assign   ! define generic assignment
  end type base_type

  type, extends(base_type) :: extended_type
     integer :: j
  end type extended_type

contains

  elemental subroutine assign (a, b)
    class(base_type), intent(out) :: a
    type(base_type), intent(in) :: b
    a%i = b%i
  end subroutine assign

  subroutine reallocate (a)
    class(base_type), dimension(:), allocatable, intent(inout) :: a
    class(base_type), dimension(:), allocatable :: tmp
    allocate (tmp (2 * size (a))) ! how to alloc b with same type as a ?
    call print_type ("tmp", tmp)
    tmp(:size(a)) = a             ! polymorphic l.h.s.
    call move_alloc (from=tmp, to=a)
  end subroutine reallocate

  subroutine print_type (name, a)
    character(*), intent(in) :: name
    class(base_type), dimension(:), intent(in) :: a
    select type (a)
    type is (base_type);      print *, name // " is base_type"
    type is (extended_type);  print *, name // " is extended_type"
    end select
  end subroutine print_type

end module realloc

program main
  use realloc
  implicit none
  class(base_type), dimension(:), allocatable :: a

  allocate (extended_type :: a(10))
  call print_type ("a", a)
  call reallocate (a)
  call print_type ("a", a)
end program main

----
This compiles and runs with NAG Fortran 5.2, and the output is:

 a is extended_type
 tmp is base_type
 a is base_type

So the type is not preserved.  To remedy this, I could write

    allocate (extended_type :: tmp (2 * size (a)))

but this requires a specific 'reallocate' for each extension of
base_type.  A single 'reallocate' containing a 'select type' clause is
not a complete solution since extensions of base_type might be defined
in any module which uses module 'realloc'.

The SOURCE argument of ALLOCATE is not allowed here.

Furthermore, it looks like I need a separate specific defined assignment
for each extension of base_type; there may be many such extensions.  I
rather would have intrinsic assignment in this situation, but this is
forbidden in F2003.

My questions:

1) Is there a simpler solution in Fortran 2003?

2) Does Fortran 2008 give a solution?  Apparently, it would remove the
need for defined assignment.  If I use MOLD, does it specify the
allocate shape?  Can I use allocate-shape-list together with MOLD to
override this setting (cf. C633)?

-- Wolfgang

--
E-mail: firstnameinitial.lastn...@domain.de
Domain: yahoo


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tobias Burnus  
View profile  
 More options Feb 1 2011, 4:36 am
Newsgroups: comp.lang.fortran
From: Tobias Burnus <bur...@net-b.de>
Date: Tue, 01 Feb 2011 10:36:37 +0100
Local: Tues, Feb 1 2011 4:36 am
Subject: Re: Sourced allocation - how is the value copied?
On 02/01/2011 09:21 AM, Wolfgang Kilian wrote:

>>> Sounds to me like what you want is the MOLD= that got added in f2008.

I concur with Richard.

>>> Umm. Anyway I think that is what MOLD= is supposed to do. I sure can't
>>> deduce that from the words of the standard, though. The standard appears
>>> to say nothing at all about what the MOLD= actually does. The complete
>>> and entire description of MOLD, other than just its syntax, appears to
>>> be
>>> "If MOLD= appears and source-expr is a variable, its value need not be
>>> defined."

I think one can deduce it from the standard, though it is not well
written. My understanding is that is allocates the variable based on the
effective type of the source-expr  in MOLD= and "assigns" the default
initializer (if existing) to it.

>    subroutine reallocate (a)
>      class(base_type), dimension(:), allocatable, intent(inout) :: a
>      class(base_type), dimension(:), allocatable :: tmp
>      allocate (tmp (2 * size (a))) ! how to alloc b with same type as a ?

Fortran 2008: MOLD=a; Fortran 2003: SOURCE=a.
The 2003 version has the disadvantage that for deeply nested derived
types with allocatable components, all those are copied/initialized as
well, while the MOLD= version matches
   allocate(effective-type-of-a :: tmp(...))

>      allocate (extended_type :: tmp (2 * size (a)))

> but this requires a specific 'reallocate' for each extension of
> base_type.  A single 'reallocate' containing a 'select type' clause is
> not a complete solution since extensions of base_type might be defined
> in any module which uses module 'realloc'.

> The SOURCE argument of ALLOCATE is not allowed here.

Sorry, I do not understand this. What prevents the use of SOURCE=a?

> Furthermore, it looks like I need a separate specific defined assignment
> for each extension of base_type; there may be many such extensions.  I
> rather would have intrinsic assignment in this situation, but this is
> forbidden in F2003.

Fortran 2008 allows an intrinsic assignment, if the LHS is allocatable.
Thus, for "tmp(:size(a)) = a" it would not work either - thus the
intrinsic assignment does not work if one wants to resize the array.

You could use a defined assignment, defined for every type extension
which adds a new component.

Otherwise, your defined assignment should work, though you could
consider to use CLASS instead of TYPE for the RHS dummy argument "b".

> 2) Does Fortran 2008 give a solution?  Apparently, it would remove the
> need for defined assignment.  If I use MOLD, does it specify the
> allocate shape?  Can I use allocate-shape-list together with MOLD to
> override this setting (cf. C633)?

I think C633 uses an inclusive or:

"C633 (R631) If allocate-object is an array either
allocate-shape-spec-list shall appear or source-expr shall appear and
have the same rank as allocate-object. If allocate-object is scalar,
allocate-shape-spec-list shall not appear."

"When an ALLOCATE statement is executed for an array for which
allocate-shape-spec-list is specified, the values of the lower bound and
upper bound expressions determine the bounds of the array. [...]"
"When an ALLOCATE statement is executed for an array with no
allocate-shape-spec-list, the bounds of source-expr determine the bounds
of the array."

Tobias

PS: I had to use an array-free version to test with gfortran as support
for polymorphic arrays is still rather incomplete [1]. Additionally,
gfortran does not like [2] if a polymorphic actual is passed to a
nonpolymorphic dummy; thus I had to change "assign". Afterwards using
SOURCE= and using MOLD= gave always the correct effective type: "is
extended_type".
[1] http://gcc.gnu.org/wiki/OOP
[2] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46990
Regarding [1]: The plan was to add array support for GCC 4.6 but too
many other OOP bugs/omissions had to be fixed (cf. bottom of [1]), thus
fixing OOP array support has been deferred to 4.7.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Wolfgang Kilian  
View profile  
 More options Feb 1 2011, 4:53 am
Newsgroups: comp.lang.fortran
From: Wolfgang Kilian <see...@domain.invalid>
Date: Tue, 01 Feb 2011 10:53:58 +0100
Local: Tues, Feb 1 2011 4:53 am
Subject: Re: Sourced allocation - how is the value copied?
On 02/01/2011 10:36 AM, Tobias Burnus wrote:

Oops -- if it was allowed, there would be no problem at all (and no need
for MOLD or defined assignment).  Actually, NAG accepts

    allocate (tmp (2 * size (a)), source=a)
    call print_type ("tmp", tmp)
    call move_alloc (from=tmp, to=a)

and both tmp and a get the correct dynamic type.  This is what I wanted
to do in the first place, I just didn't dare ...

However, is this really standard-conforming?  The F2003 draft, p.112 l.7
says

If SOURCE= appears, source-expr shall be conformable (2.4.5) with
allocation.

My understanding is that a and tmp are not conformable if I double the
size.  Maybe this is a misinterpretation?  However, is it obvious where
the source is to be copied in the enlarged array?  Will the remaining
part be default-initialized correctly?  What if the allocated size is
smaller than a?

-- Wolfgang
--
E-mail: firstnameinitial.lastn...@domain.de
Domain: yahoo


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Wolfgang Kilian  
View profile  
 More options Feb 1 2011, 5:04 am
Newsgroups: comp.lang.fortran
From: Wolfgang Kilian <see...@domain.invalid>
Date: Tue, 01 Feb 2011 11:04:52 +0100
Local: Tues, Feb 1 2011 5:04 am
Subject: Re: Sourced allocation - how is the value copied?
On 02/01/2011 10:53 AM, Wolfgang Kilian wrote:

>     allocate (tmp (2 * size (a)), source=a)
>     call print_type ("tmp", tmp)
>     call move_alloc (from=tmp, to=a)

> and both tmp and a get the correct dynamic type.  This is what I wanted
> to do in the first place, I just didn't dare ...

> However, is this really standard-conforming?  The F2003 draft, p.112 l.7
> says

> If SOURCE= appears, source-expr shall be conformable (2.4.5) with
> allocation.

Note added: When I turn on bounds checking in nagfor, I get a runtime
error.  This is what I expected.  I don't think this use of SOURCE can
possibly be conforming ...

-- Wolfgang

--
E-mail: firstnameinitial.lastn...@domain.de
Domain: yahoo


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Wolfgang Kilian  
View profile  
 More options Feb 1 2011, 5:08 am
Newsgroups: comp.lang.fortran
From: Wolfgang Kilian <see...@domain.invalid>
Date: Tue, 01 Feb 2011 11:08:24 +0100
Local: Tues, Feb 1 2011 5:08 am
Subject: Re: Sourced allocation - how is the value copied?
On 02/01/2011 10:36 AM, Tobias Burnus wrote:

> On 02/01/2011 09:21 AM, Wolfgang Kilian wrote:
>>>> Sounds to me like what you want is the MOLD= that got added in f2008.

> You could use a defined assignment, defined for every type extension
> which adds a new component.

> Otherwise, your defined assignment should work, though you could
> consider to use CLASS instead of TYPE for the RHS dummy argument "b".

That was my first attempt, but it didn't work (NAG didn't accept it),
once I wrote specifics for both base_type and extended_type.  I guess
because the specific procedures for the generic assignment can't be
distinguished unambiguously.

-- Wolfgang

--
E-mail: firstnameinitial.lastn...@domain.de
Domain: yahoo


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »