Fortran中的副本分配和构造函数之间的冲突

时间:2019-04-07 14:19:56

标签: fortran intel-fortran

我有以下代码会产生分段错误。它确实抱怨

  

forrtl:严重(408):堡垒:(7):当指针TT与目标未关联时,尝试使用指针

现在,我很确定原因是什么,也就是它试图访问我的copy分配例程,而我只是试图初始化该对象。

通过注释generic :: assignment(=) => copy可以正常工作!

我正在按以下方式编译代码:(IFORT版本19.0.3) ifort -O0 -debug full -check all -traceback -g -C -CB -CU -CA -fpp filaname.f90 并由./a.out

运行
   module md

   implicit none

   type T_TEST

      integer :: ii

   contains
         procedure, pass(this)               :: COPY
       generic :: assignment(=) => copy

   end type


   interface t_test
      module procedure init
   end interface t_test


   type(t_test) , allocatable :: tt


contains
   function init( size )
      integer, intent(in)                   :: size
      type(t_test) , allocatable           :: init


      allocate( init )
      init% ii = size
   end function

   subroutine copy(this, old )

      class(t_test), intent(out)  ::this
      type(t_test), intent(in) :: old


       this% ii = old% ii

   end subroutine

end module md

program t_Testprogram
use md
implicit none

tt = t_test( 100 )

end program t_Testprogram

1 个答案:

答案 0 :(得分:3)

原因是过载的copy不支持可分配的左侧。因此,当在this中使用this% ii = old% ii的值时,它实际上不存在,并且使用了空指针。但是我确实同意英特尔的错误消息令人困惑甚至不正确。

自动左侧(重新)分配仅适用于内部分配,不适用于用户定义的分配。在用户定义的程序中,您必须对自己的确切行为进行编程。而且您没有为未分配的左侧指定任何内容。

这对我有用:

   type T_TEST

      integer :: ii

   end type


   interface assignment(=)
     procedure copy
   end interface


   subroutine copy(this, old )

      class(t_test), allocatable, intent(out)  ::this
      type(t_test), intent(in) :: old

       if (.not.allocated(this)) allocate(this)
       this% ii = old% ii

   end subroutine

或者您可以先分配对象(这就是我要做的,因为gfortran似乎不喜欢基于可分配属性的通用解析-F08功能)。

allocate(tt)
tt = t_test( 100 )

您似乎在想,仅仅因为构造函数的结果变量被“标记” allocatable,它就会为您分配分配的左侧。 不是。它唯一要做的就是将自己的结果分配为一个临时变量。然后将此结果分配到tt = t_test()中,然后自动释放。

请记住,结果变量与分配的左侧相同。结果可以用在许多不同类型的表达式中,而不仅仅是在赋值中。它可以传递给子例程,可以在算术表达式中使用,可以打印...

您的构造函数可以只是

   function init( size )
      integer, intent(in)                   :: size
      type(t_test)           :: init

      init% ii = size
   end function

,结果将完全相同。没有理由使它可分配,只会使其复杂化,而丝毫不会改变结果。

也许您正在尝试遵循某些C ++ RAII原则,但是请记住,C ++根本不是Fortran。