arrays - `PACK` 的 Fortran 多态数组赋值:问题
问题描述
我正在尝试PACK
在多态数组上编写一个计算效率高的操作,并且我正在运行以下问题gfortran 9.2.0
:
- 该
PACK
操作必须在派生类型数量的多态数组上工作,并在其自身上返回结果 - 由于我不在这里解释的原因,这个数组不应该被重新分配
- 通常,返回索引的位置与原始数组的位置之间存在重叠:类似于
array(1:5) = array([2,4,6,8,10])
我遇到了问题,因为我尝试使用 gfortran 的唯一分配版本是带有循环的 - 所有基于数组的版本都会产生编译器或运行时段错误。
本程序报告了一个例子:
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))
直到您希望报告的错误得到修复。
推荐阅读
- javascript - 在 Bootstrap 5 轮播中分别为字幕和幻灯片制作动画?
- opayo - Opayo 3ds2 - sagepay PI 集成 rsa3dsauth.co.uk 无法返回三个DSSessionData
- python - Python OPC UA 将变量传递给 uamethod
- javascript - 创建 csv 文件时编码符号
- java - 如何知道用户是从特定位置经过还是错过了该位置
- javascript - 如果有类活动 jQuery,如何删除 DataTable 中的完整行
- python - 在将列与 Python Pandas 组合时重塑(融化?)数据
- javascript - 在从页面底部计数的特定像素数上触发事件
- java - Spring-boot JPA无限循环多对多
- java - 如何在 Spinner 中进行分组