On Friday, July 17, 2020 at 4:33:43 AM UTC+9, FortranFan wrote:
> You can refer to section 7.5.10 Construction of derived-type values in the standard for details - see paragraph 5:
>
> "For a pointer component, the corresponding component-data-source shall be an allowable data-target or proc-target for such a pointer in a pointer assignment statement (10.2.2). If the component data source is a pointer, the association of the component is that of the pointer; otherwise, the component is pointer associated with the component data source"
Thanks very much! Though I'm not 100% sure whether I've understood the above
description (from the Standard), it looks like if the actual argument (in the structure
constructor) is a pointer, then the metadata of the latter pointer is copied to that of the
component of the structure. So the overall behavior seems similar to a copy of an object
with pointer components (obj2 = obj1).
# My motivation for this question is that I wanted to add a new element of BaseRef
to "arr", such that
arr = [ arr, BaseRef( p ) ]
which seems to work as expected (though this is costly for an array with many
elements...)
----- test3.F90 (to check the address of components) -----
program main
use iso_c_binding
implicit none
type Base ; endtype
type, extends(Base) :: Type1 ; endtype
type, extends(Base) :: Type2 ; endtype
type BaseRef
class(Base), pointer :: p
endtype
type(BaseRef), allocatable :: refs(:)
class(Base), pointer :: p1, p2, p2_more
integer i
allocate( Type1 :: p1 )
allocate( Type2 :: p2 )
allocate( Type2 :: p2_more )
selecttype ( p1 ); type is (Type1)
print "(a,z0)", "p1(addr) = ", c_loc( p1 )
endselect
selecttype ( p2 ); type is (Type2)
print "(a,z0)", "p2(addr) = ", c_loc( p2 )
endselect
selecttype ( p2_more ); type is (Type2)
print "(a,z0)", "p2_more(addr) = ", c_loc( p2_more )
endselect
refs = [ BaseRef( p1 ), BaseRef( p2 ) ] !! auto-alloc of LHS
!! Add one more variable.
refs = [ refs, BaseRef( p2_more ) ]
do i = 1, size(refs)
print *, "i = ", i
selecttype ( p => refs( i )% p )
type is (Type1) ; print "(a,z0)", "-> Type1: p(addr) = ", c_loc( p )
type is (Type2) ; print "(a,z0)", "-> Type2: p(addr) = ", c_loc( p )
endselect
enddo
end
-----
# Though not related to the question, I strongly feel that the above code illustrates
the tediousness of treating heterogeneous (inhomogeneous) data in Fortran...
Indeed, I feel it like more like a "puzzle" when writing the code (as compared to other
languages, where class variables are references and there is no need to wrap pointers).
Things might change if some new syntax for "array of pointers" may be introduced in
future, but not very sure if it's possible (because many other syntaxes assume
homogeneous / rectangular nature of array elements).