Allocatable arrays inside fortran classes with pgf90 compiler

I have a question regarding utilization of allocatable array of allocatable characters.

character(:), allocatable :: lines(:)

wrapped inside a class: like:

type, public :: t_c
character(:), allocatable :: line
character(:), allocatable :: lines(:)
end type t_c

type(t_c) :: t

Basically t%lines(:) does not work. I tried with pgf90. v.19+

The test code is shown below:

The sample code shown bellow does not work for
wrapped within t_c character(:), allocatable :: lines(:)


Is this a bug?

module m_c

type, public :: t_c
character(:), allocatable :: line
character(:), allocatable :: lines(:)
end type t_c

end module m_c

program main
use m_c
implicit none
type(t_c) t
character(:),allocatable :: line, lines(:)
integer i
t%line = 'a test for t%line ’

line=’ 1: line 1 ; this is the line number 1 ; and so on ’

allocate(character(len=len(line))::lines(3))
lines(1) = line
lines(2) = ’ intra-group overwrite’
lines(3) = ’ modify gauss ’

!t%lines = lines ! try 1 : not working
!allocate(t%lines , source = lines) ! try 2 ; not working

allocate(character(len(line))::t%lines(3))
! note printing len(t%lines(1)) gives 2
do i =1,3; t%lines(i)=lines(i); enddo ! stiill not workin

t%line = ’ a single line may be ok 111111111111111222222333’

do i = 1,3
print*,len(lines(i)),len(t%lines(i)),‘t_c ="’,t%lines(i),‘"’
enddo

print*,len(line), ‘t%line=’,t%line
end program main

What error are you seeing? When I uncomment out the try1 and try2 lines, I see an error that the array is already allocated with both nvfortran (same as pgf90) and gfortran. The error is correct since “t%lines” is getting allocated three times in this case. Picking one allocation style, implicitly (TRY1), sourced (TRY2), or just allocated, all work as expected.

If this is not the error you’re seeing, please modify the example to recreate the error and provide an the error message you’re seeing.

% cat test.F90
module m_c

type, public :: t_c
character(:), allocatable :: line
character(:), allocatable :: lines(:)
end type t_c

end module m_c

program main
use m_c
implicit none
type(t_c) t
character(:),allocatable :: line, lines(:)
integer i
t%line = "a test for t%line "

line=" 1: line 1 ; this is the line number 1 ; and so on "

allocate(character(len=len(line))::lines(3))
lines(1) = line
lines(2) = ' intra-group overwrite'
lines(3) = ' modify gauss '

#if defined(TRY1)
t%lines = lines ! try 1 : not working
#elif defined(TRY2)
allocate(t%lines , source = lines) ! try 2 ; not working
#else
allocate(character(len(line))::t%lines(3))
#endif
! note printing len(t%lines(1)) gives 2
do i =1,3; t%lines(i)=lines(i); enddo ! stiill not workin

t%line = " a single line may be ok 111111111111111222222333"

do i = 1,3
print*,len(lines(i)),len(t%lines(i)),'t_c =',t%lines(i)
enddo

print*,len(line), 't%line=',t%line
end program main
% nvfortran test.F90 -DTRY1 ; a.out
           51            2 t_c = 1
           51            2 t_c = i
           51            2 t_c = m
           51 t%line= a single line may be ok 111111111111111222222333
% nvfortran test.F90 -DTRY2 ; a.out
           51            2 t_c = 1
           51            2 t_c = i
           51            2 t_c = m
           51 t%line= a single line may be ok 111111111111111222222333
% nvfortran test.F90 ; a.out
           51            2 t_c = 1
           51            2 t_c = i
           51            2 t_c = m
           51 t%line= a single line may be ok 111111111111111222222333
% gfortran test.F90 ; a.out
          51          51 t_c = modify gauss
          51          51 t_c = modify gauss
          51          51 t_c = modify gauss
          51 t%line= a single line may be ok 111111111111111222222333
% gfortran test.F90 -DTRY1 ; a.out
          51          51 t_c = modify gauss
          51          51 t_c = modify gauss
          51          51 t_c = modify gauss
          51 t%line= a single line may be ok 111111111111111222222333
% gfortran test.F90 -DTRY2 ; a.out
          51          51 t_c = modify gauss
          51          51 t_c = modify gauss
          51          51 t_c = modify gauss
          51 t%line= a single line may be ok 111111111111111222222333

Thanks for fast replay.
Note that in your modified example “test.F90” the gcc/10.2.0 prints different (and correct) results than in your example.

      51          51 t_c = 1: line 1 ; this is the line number 1 ; and so on
      51          51 t_c = intra-group overwrite
      51          51 t_c = modify gauss
      51 t%line= a single line may be ok 111111111111111222222333

But let us consider a simpler example, which allocate an allocatable character(:), allocatable :: lines(:) embeded into a class/type.

My question is: why the len of t%lines(:) gets printed to “2” from “90” ?

module m_c
type, public :: t_c
character(:), allocatable :: one_line
character(:), allocatable :: lines(:)
end type t_c
end module m_c

program main
use m_c
implicit none
type(t_c) t
character(:),allocatable :: one_line, lines(:)
integer :: i, Nlen3 = 90

one_line = 'a test for t%line ’
t%one_line = one_line ! the len of t%one_line shall be the same with the len of one_line

allocate(character( Nlen3 ) :: t%lines(3)) ! the len of lines(1:3) shall be Nlen3 (which is 90)

! note printing len(t%lines(1)) gives 2
print*,‘— for arrays: t%lines(1:3):’
do i = 1,3
print*,i, ’ compare len(): ‘,len(t%lines(i)), ‘==’, Nlen3, ’ ? ‘,len(t%lines(i))==Nlen3
! the result shal len(t%lines(i)) == Nlen3 == 90
enddo
print*
print*,’— for scalar: t%one_line’
print*,len(one_line), ‘==’ ,len(t%one_line), ’ ? ', len(one_line)==len(t%one_line)

end program main

with pgf90 (18 or 19+), above code print:

— for arrays: t%lines(1:3):
1 compare len(): 2 == 90 ? F
2 compare len(): 2 == 90 ? F
3 compare len(): 2 == 90 ? F

— for scalar: t%one_line
18 == 18 ? T

Why len(t%lines(1:3) gets printed to “2” when they where allocated to “90” 1-2 lines above?
With gfortran:
— for arrays: t%lines(1:3):
1 compare len(): 90 == 90 ? T
2 compare len(): 90 == 90 ? T
3 compare len(): 90 == 90 ? T

— for scalar: t%one_line
18 == 18 ? T

Apologies. I wasn’t paying attention to the output, only the multi-allocations. Thanks for the update and clarification.

This looks like a compiler issue so I’ve filed a problem report, TPR #29354, and sent it to engineering for further investigation.

Thanks!
Mat

Hi u0615401,

Engineering let me know that they have TPR #29354 fixed in our 23.7 release.

% nvfortran test.f90 -V23.7 ; a.out
 — for arrays: t%lines(1:3):
            1 compare len():            90 ==           90  ?   T
            2 compare len():            90 ==           90  ?   T
            3 compare len():            90 ==           90  ?   T

 — for scalar: t%one_line
           18 ==           18  ?   T

-Mat