Я пытаюсь создать процедуру, которая может принимать разные типы ввода без использования общей процедуры.Действительно (в данном случае) я предпочитаю вручную устанавливать цель указателя процедуры, чтобы определить, какую процедуру использовать, а не общую процедуру.
Это то, что я делаю со следующим почти минимальным примером.
module mo
implicit none
type :: TypeB
character(len=5) :: info='Hello'
contains
procedure, pass(fd) :: say_hello
end type TypeB
type :: TypeA
character(len=4) :: txt='Hola'
!type(TypeB) :: Tb
end type TypeA
type, extends(TypeA) :: TypeC
character(len=4) :: tt='Hey!'
type(TypeB) :: Tb
end type TypeC
type, extends(TypeA) :: TypeD
character(len=3) :: tt='Ho!'
character(len=3) :: ti='you'
!type(TypeB) :: Tb
end type TypeD
type(TypeC) :: Tc
type(TypeD) :: Td
procedure(), pointer :: proc
class(TypeA), allocatable :: CA
contains
subroutine say_hello(fd)
implicit none
! type(TypeB), intent(inout) :: fd
class(TypeB), intent(inout) :: fd
print *, fd%info
end subroutine say_hello
subroutine procC(fd, args)
implicit none
! class(TypeC), intent(inout) :: fd
type(TypeC), intent(inout) :: fd
real :: args
print*, args
print*, fd%tt
call fd%Tb%say_hello()
end subroutine procC
subroutine procD(fd, args)
implicit none
! class(TypeD), intent(inout) :: fd
type(TypeD), intent(inout) :: fd
! class(TypeA), intent(inout) :: fd
real :: args
print*, args
print*, fd%tt
print*, fd%ti
end subroutine procD
end module mo
program p
use mo
implicit none
print* , 'START'
print *, Tc%tb%info
print *, Tc%txt
call Tc%Tb%say_hello()
call procC(Tc, 1.0)
call procD(Td, 2.0)
print*, 'OK'
allocate(TypeD :: CA)
proc =>procD
call proc(CA, 3.0)
deallocate(CA)
allocate(TypeC :: CA)
proc =>procC
call proc(CA, 4.0)
deallocate(CA)
print*, 'END'
end program p
Я получаю ожидаемые результаты при компиляции с помощью ifort в Linux, но при компиляции с помощью gfortran (MinGW 6.2.0) в Windows или в Linux (gfortran 5.5.0 и 6.4.0) я получаю что-тостранно:
START
Hello
Hola
Hello
1.00000000
Hey!
Hello
2.00000000
Ho!
you
OK
3.00000000
@R
4.00000000
ÇR@
END
И все становится хуже, когда я использую этот метод в своей большой программе с ошибкой сегментации.
Итак, есть ли способ избежать этих проблем?Это ошибка Gfortran?Или я что-то неправильно понимаю?