问题
I would like to create a derived type containing allocatable character array components. However, when I try to allocate memory in subroutines, nothing happens. It may be more clear with the code example below:
program test
type t1
character(len=:), allocatable :: c(:)
end type t1
type(t1) :: t
call test_string1()
call test_string2(t)
contains
subroutine test_string1()
character(len=:), allocatable :: c(:)
allocate( character(10) :: c(1) )
write(*, *) 'Size in string1: ', len(c)
end subroutine test_string1
subroutine test_string2(this)
class(t1) :: this
allocate( character(10) :: this%c(1) )
write(*, *) 'Size in string2: ', len(this%c)
end subroutine test_string2
end program test
I expect that the output of such a code would be:
Size in string1: 10
Size in string2: 10
However, what I actually get is the following:
Size in string1: 10
Size in string2: 0
Therefore, the second subroutine allocates nothing for the t1%c
... What am I doing wrong here ?
I have compiled the code with:
gfortran -c test.f08
gfortran -o test test.o
and the version of gfortran
is the following:
$ gfortran -v
...
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
回答1:
This is a bug (or lack of support) in the version of the compiler you are using. In gfortran versions 7 and 8 I see the same problem, but as noted, gfortran 9 gives the expected answer. "Use a different compiler/version" is an answer to your question.
What is sometimes helpful in cases like this is the additional question: "what can I do to work around this bug without changing compiler?"
The example of the question is fairly simple leading to not many options. Intrinsic assignment of a constructed array, or sourced allocation don't help.
Is there something interesting that does? Why, yes! Parameterized derived types.
It appears that gfortran 8 experiences the problem of the question but does support derived type parameterization (gfortran 7 doesn't support this Fortran 2003 feature). This could be a good work around, or even a good alternative approach to the real problem:
program test
type t1(length, size)
integer, len :: length, size
character(len=length) :: c(size)
end type t1
class(t1(:,:)), allocatable :: t
call test_string1()
call test_string2(t)
contains
subroutine test_string1()
character(len=:), allocatable :: c(:)
allocate( character(10) :: c(1) )
write(*, *) 'Size in string1: ', len(c)
end subroutine test_string1
subroutine test_string2(this)
class(t1(:,:)), allocatable :: this
allocate( t1(10,1) :: this )
write(*, *) 'Size in string2: ', len(this%c)
end subroutine test_string2
end program test
来源:https://stackoverflow.com/questions/60166578/wrong-length-of-a-character-array-component-after-allocation