我想创建一个包含可分配字符数组组件的派生类型。但是,当我尝试在子例程中分配内存时,什么也没有发生。下面的代码示例可能更清楚:
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
我希望此类代码的输出为:
Size in string1: 10
Size in string2: 10
但是,我实际得到的是以下内容:
Size in string1: 10
Size in string2: 0
因此,第二个子例程未为t1%c
分配任何内容...我在这里做错了什么?
我用以下代码编译了代码:
gfortran -c test.f08
gfortran -o test test.o
,gfortran
的版本如下:
$ gfortran -v
...
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
答案 0 :(得分:1)
这是您使用的编译器版本中的错误(或缺乏支持)。在gfortran版本7和8中,我看到了相同的问题,但是如上所述,gfortran 9提供了预期的答案。 “使用其他编译器/版本”是您的问题的答案。
在这种情况下有时有用的是附加问题:“在不更改编译器的情况下,我该怎么办才能解决此错误?”
该问题的示例非常简单,导致没有太多选择。构造数组的内部分配或源分配都无济于事。
有有趣的事情吗?为什么是!参数化派生类型。
看来gfortran 8遇到了问题,但确实支持派生类型参数化(gfortran 7不支持此Fortran 2003功能)。这可能是一个很好的解决方法,或者甚至是解决实际问题的一种很好的替代方法:
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