Fortran中复制赋值和构造函数之间的冲突

问题描述 投票:1回答:1

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

forrtl:severe(408):fort:(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
fortran intel-fortran
1个回答
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似乎不喜欢基于allocatable属性的通用解析 - 一个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。

© www.soinside.com 2019 - 2024. All rights reserved.