Arrays “PACK”的Fortran多态数组分配:问题
我试图在多态数组上编写一个计算效率高的Arrays “PACK”的Fortran多态数组分配:问题,arrays,fortran,polymorphism,Arrays,Fortran,Polymorphism,我试图在多态数组上编写一个计算效率高的PACK操作,我正在处理gfortran 9.2.0的问题: PACK操作必须处理派生类型数量的多态数组,并在其自身返回结果 由于我在这里没有解释的原因,这个数组不应该被重新分配 通常,返回索引的位置与原始数组的位置之间存在重叠:类似于array(1:5)=array([2,4,6,8,10]) 我遇到了一些问题,因为我用gfortran尝试过的唯一一个assigment版本是一个循环——所有基于数组的版本要么产生编译器错误,要么产生运行时错误 本程序中
PACK
操作,我正在处理gfortran 9.2.0
的问题:
操作必须处理派生类型数量的多态数组,并在其自身返回结果PACK
- 由于我在这里没有解释的原因,这个数组不应该被重新分配
- 通常,返回索引的位置与原始数组的位置之间存在重叠:类似于
array(1:5)=array([2,4,6,8,10])
module m
implicit none
type, public :: t
integer :: i = 0
contains
procedure, private, pass(this) :: t_assign => t_to_t
generic :: assignment(=) => t_assign
end type t
type, public, extends(t) :: tt
integer :: j = 0
contains
procedure, private, pass(this) :: t_assign => t_to_tt
end type tt
contains
elemental subroutine t_to_t(this,that)
class(t), intent(inout) :: this
class(t), intent(in ) :: that
this%i = that%i
end subroutine t_to_t
elemental subroutine t_to_tt(this,that)
class(tt), intent(inout) :: this
class(t ), intent(in ) :: that
this%i = that%i
select type (thatPtr=>that)
type is (t)
this%j = 0
type is (tt)
this%j = thatPtr%j
class default
! Cannot stop here
this%i = -1
this%j = -1
end select
end subroutine t_to_tt
end module m
program test_poly_pack
use m
implicit none
integer, parameter :: n = 100
integer :: i,j
class(t), allocatable :: poly(:),otherPoly(:)
allocate(t :: poly(n))
allocate(t :: otherPoly(10))
! Assign dummy values
forall(i=1:n) poly(i)%i = i
! Array assignment with indices => ICE segfault:
! internal compiler error: Segmentation fault
otherPoly(1:10) = poly([10,20,30,40,50,60,70,80,90,100])
! Scalar assignment with loop -> OK
do i=1,10
otherPoly(i) = poly(10*i)
end do
! Array assignment with PACK => Compiles OK, Segfault on runtime. GDB returns:
! Thread 1 received signal SIGSEGV, Segmentation fault.
! 0x000000000040163d in m::t_to_t (this=..., that=...) at test_poly_pack.f90:31
! 31 this%i = that%i
otherPoly(1:10) = pack(poly,mod([(j,j=1,100)],10)==0)
do i=1,10
print *, ' polymorphic(',i,')%i = ',otherPoly(i)%i
end do
end program test_poly_pack
我是否做错了什么,和/或这只是一个编译器错误,或者我应该遵循任何最佳实践?崩溃是编译器错误。当编译器显示内部编译器错误时。。。请提交一份完整的错误报告,您确实可以信任它,您应该采取相应的行动(并提交错误报告)。运行时崩溃也是一个编译器错误(错误代码) 如果在分配时知道实际类型,则可以使用类型保护
select type (p => poly)
type is (t)
select type(op => otherpoly)
type is (t)
op(1:10) = pack(p,mod([(j,j=1,100)],10)==0)
end select
end select
如果你需要它是多态的-你可能需要重新分配
allocate(otherPoly(1:10),source = pack(poly,mod([(j,j=1,100)],10)==0))
直到您希望报告的错误被修复。您真的应该显示错误消息。并更新您的编译器。您是否收到消息说内在赋值不能是多态的?请注意,
allocate(otherPoly(1:10),source=pack(poly,mod([(j,j=1100)],10)==0))
工作正常。如果编译器中出现SEGFULT,则是编译器中的错误。你必须向GCC报告,我们真的帮不了你。错误消息说,请提交完整的错误报告。您的确切问题是什么?谢谢,我添加了与错误相关的输出问题是什么是这方面的最佳实践:由于阵列版本似乎存在问题,什么是不需要临时分配的计算效率高的实现?嗯,我看不出有什么可能的答案,显然,这取决于编译器中的bug,我看不出你会做错什么。你只是在找一个解决办法吗?目前,重新分配可能是最好的。直到您报告的bug得到修复。或者使用没有这些bug的编译器。谢谢,这两种解决方法都可以在gfortran
中正常工作。正如您所说的,它们都不太符合面向对象编程的精神,而面向对象编程(在工作时)极大地简化了语法。当我发布这个问题时,我认为即使对于Fortran来说,这也是非常基本的OO内容,我一定是做错了什么。@FedericoPerini我不知道如何更清楚地重复它。这是一个编译器错误。你没有做错什么。您应该向GCC报告该错误。这就是全部。