Я хотел бы знать, возможно ли в современном Фортране назначить выделяемый массив, используя себя или его часть для этого. Вот простой пример:
module modu
implicit none
type :: t
integer :: i
end type
contains
subroutine assign(a,b)
type(t), allocatable, intent(out) :: a(:)
type(t), intent(in) :: b
allocate(a(1))
a(1) = b
end subroutine
end module
!----------------------
program test
use modu
implicit none
type(t), allocatable :: a(:)
allocate(a(1))
a(1)%i = 2
call assign(a, a(1))
print*, a(1)%i
end program
Этот код дает ответ corect с ifort 18 и возвращает "Segmentation fault" с gfortran 7.4.
ПРИМЕЧАНИЕ. Исходная проблема была немного более сложной, так как call assign(a, a(1))
следует заменить на call assign(a, a(1)+b)
с должной перегрузкой operator +, но вывод (с уважением к ifort и gfortran) тот же.
ПРИМЕЧАНИЕ. В потоке проверка самоназначения в перегруженном назначении fortran, @IanH делает различие между call assign(a,a)
и call assign(a,(a))
, но я считаю, что это не решает эту проблему, потому что у меня есть аргументы, которые можно распределять.
ПРИМЕЧАНИЕ. В потоке Автоматическое выделение массива при назначении в Fortran, @ francescalus объясняет автоматическое распределение по внутреннему присваиванию, но я снова считаю, что здесь это не применимо.