On Sep 24, 2016, at 8:48 AM, Vipul Parekh <[log in to unmask]> wrote:
> A correction - in the beginning section of this note, I meant to write:
>
> Is it then possible to introduce an added facility for coders involving CHARACTER variables and CHARACTER arrays in pointer assignment as following:
>
> character(kind=CK,len=n*ell), target :: s ! n, ell are constants
> character(kind=CK,len=ell), pointer :: t(1:n) => s ! not allowed currently, but can it be?
>
> That is, the type and kind of character data on both sides of the assignment are the same, only the rank is different.
More importantly, the length type parameters are different. This is want causes this to be not allowed.
Cheer,
Bill
>
> Apologies for any confusion,
> Vipul
>
> On Sat, Sep 24, 2016 at 9:43 AM, Vipul Parekh <[log in to unmask]> wrote:
> Starting with Fortran 2003, the remapping of the elements of a rank-one array is permitted in pointer assignment. Hence one can do:
> ..
> integer, target :: a(m*m) ! say m is a constant
> integer, pointer :: p(:,:)
> ..
> p(1:m,1:m) => a(1:m*m)
>
> Is it then possible to introduce an added facility for coders involving CHARACTER variables and CHARACTER arrays in pointer assignment as following:
>
> character(kind=CK,len=n*ell), target :: s ! n, ell are constants
> character(len=ell), pointer :: t(1:n) => s ! not allowed currently, but can it be?
>
> In my simple-minded thinking, I tend to view both of above as just involving association with length-type of information of the objects on either side of the assignment. But one is allowed by the standard while the other is not. What is it about character type in Fortran that might make the above remapping not possible?
>
> Because one combine the facility of argument association with pointer assignment to mimic the above, so why can't then the language offer an abstraction which does such an action 'behind the scenes' and thus offers a compact option for the coder?
>
> -- begin code --
> module m
>
> use, intrinsic :: iso_fortran_env, only : character_kinds
> use, intrinsic :: iso_c_binding, only : c_loc, c_intptr_t
>
> implicit none
>
> integer, parameter :: CK = character_kinds(2)
> integer, parameter :: n = 3
> integer, parameter :: ell = 4
>
> character(kind=CK, len=n*ell), target :: s
> character(kind=CK, len=ell), pointer :: t(:) => null()
>
> private :: set
>
> contains
>
> subroutine set_t()
>
> call set(s,t)
>
> end subroutine set_t
>
> subroutine set(string, pstring)
>
> character(kind=CK,len=ell), intent(in), target :: string(n)
> character(kind=CK,len=ell), intent(out), pointer :: pstring(:)
>
> pstring(1:n) => string(1:n)
>
> end subroutine set
>
> subroutine output_addresses( x, s1, s2 )
>
> integer, intent(in) :: x
> character(kind=CK, len=*), intent(in), target :: s1
> character(kind=CK, len=*), intent(in), target :: s2
>
> integer(c_intptr_t) :: add_1
> integer(c_intptr_t) :: add_2
>
> add_1 = transfer( c_loc(s1), mold=add_1)
> add_2 = transfer( c_loc(s2), mold=add_2)
> print "(1x,i0,3x,z0,24x,z0)", x, add_1, add_2
>
> return
>
> end subroutine output_addresses
>
> end module m
> program p
>
> use m, only : s, t, output_addresses, n, ell, set_t
>
> implicit none
>
> integer :: i
> integer :: j
> integer :: k
>
> call set_t()
>
> do i = 1, n*ell
> s(i:i) = achar(96+i, kind=kind(S))
> end do
>
> print *, "Values"
> print *, "i j k s(k:k) t(i)(j:j)"
> do i = 1, n
> do j = 1, ell
> k = (i-1)*ell + j
> print "(1x,i0,3x,i0,3x,i0,3x,g0,7x,g0)", i, j, k, s(k:k), t(i)(j:j)
> end do
> end do
>
> print *, "Addresses in memory"
> print *, "i s((i-1)*ell+1:(i-1)*ell+1) t(i)"
> do i = 1, n
> call output_addresses( i, s((i-1)*ell+1:(i-1)*ell+1), t(i) )
> end do
>
> stop
>
> end program p
> -- end code --
>
> Upon execution with gfortran which supports a second character kind,
>
> -- begin output --
> Values
> i j k s(k:k) t(i)(j:j)
> 1 1 1 a a
> 1 2 2 b b
> 1 3 3 c c
> 1 4 4 d d
> 2 1 5 e e
> 2 2 6 f f
> 2 3 7 g g
> 2 4 8 h h
> 3 1 9 i i
> 3 2 10 j j
> 3 3 11 k k
> 3 4 12 l l
> Addresses in memory **
> i s((i-1)*ell+1:(i-1)*ell+1) t(i)
> 1 448020 448020
> 2 448030 448030
> 3 448040 448040
>
> -- end output --
>
> ** the use of c_loc is questionable but I figure it's handy here.
>
> So to summarize, are there rules or constraints or some flexilibility offered to implementations involving non-default and non-c_char character kinds that make the following compact representation not possible?
>
> character(kind=CK, len=n*ell), target :: s
> character(kind=CK, len=ell), pointer :: t(1:n) => s
>
> The language has type, kind, and rank (TKR) restrictions on pointer remapping and I would expect any potential enhancement to character variables and arrays will retain the same. So I would expect whatever an implementation might be doing for a non-default character kind would be immaterial, especially when the remapping that is permitted is to a rank-one array as is the case currently in the standard. John Reid writes in "The New Features of Fortran 2003", "The limitation to rank-one arrays is because pointer arrays need not occupy contiguous storage: .. but all the gaps have the same length in the rank-one case."
>
> Thanks much in advance,
> Vipul Parekh
>
Bill Long [log in to unmask]
Fortran Technical Support & voice: 651-605-9024
Bioinformatics Software Development fax: 651-605-9142
Cray Inc./ Cray Plaza, Suite 210/ 380 Jackson St./ St. Paul, MN 55101
|