On Friday, September 23, 2016 at 6:03:51 PM UTC-4, Ian Harvey wrote:
> ..
>
> Take `ell` to be three and `n` to be four, and some_char_kind to be not
> the value for default character kind and not C_CHAR, ..
>
> Those two layouts can currently be incompatible. Your proposal would
> require them to be the same (so that "all the gaps have the same
> length", as you quote from John Reid, would be true), practically, even
> if a program did not use the proposed feature.
>
> (If your proposal only applied to default character or C_CHAR character
> kind scalars, then it would not introduce any additional constraints on
> storage.)
>
> .. But there is
> more than a hint of regret around the implications that things like
> sequence and storage association have on alignment requirements and
> optimisation today. I suspect that regret is one of the reasons that
> non-default, non-C_CHAR character kinds have been explicitly excluded
> from the sequence and storage association rules.
>
> ..
I see the following in the standard:
section
16.3.5.4: "Partial association shall exist only between an object that is default character or of character sequence type and an object that is default character or of character sequence type .."
and a bit later in the same section,
"For character entities, partial association may occur only through argument association or the use of COMMON or EQUIVALENCE statements."
So are you saying when it comes to character storage units of a non-default or non-c_char kind, the association that occurs with argument association or the use of EQUIVALENCE cannot be replicated in an enhanced facility of pointer remapping? FJ's suggestion upthread nicely combines what the facility of argument association with pointer assignment, I wish I can better understand why the language can't offer an abstraction along such lines which a coder can use:
-- 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, my silly 'brainwave' was if a coder could do above, can't the following be allowed as a compact representation:
character(kind=CK, len=n*ell), target :: s
character(kind=CK, len=ell), pointer :: t(1:n) => s
So if I understand your point correctly, it may work with c_char and default char kinds of most compilers today and also perhaps (based on above example) with CHARACTER_KINDS(2) in gfortran, but not so in the general case. Interesting, though I'll never quite understand the finer details, suffice it to say it is yet another thought that goes up in flames!
Thanks for your attention,