Да, внутренние функции обычно передаются с использованием трамплинов, поэтому необходим исполняемый стек.
я есть некоторый код, который передает внутреннюю функцию основной программы в качестве аргумента функции: когда переданная функция в конечном итоге вызывается, это вызывает ошибку сегментации. Это происходит только тогда, когда я использую подсистему Windows для Linux (я использую Ubuntu 16 на WSL); на родных машинах Linux или Mac этого не происходит.
Минимальный пример сбоя:
module test1
implicit none
contains
subroutine x(ff,y)
interface
real function ff(y)
real, intent(in) :: y
end function ff
end interface
real, intent(in) :: y
integer z
z=ff(y)
end subroutine x
end module test1
program tester
use test1
implicit none
call x(f,1.0)
contains
real function f(y)
real, intent(in) :: y
write(*,*) y
f=y*y
end function f
end program tester
Составлено с:
gfortran-7 -ggdb test_fun_passing.f90 -o test
Обратный след, вывод GDB:
(gdb) bt
#0 0x00007ffffffde320 in ?? ()
#1 0x0000000000400734 in test1::x (ff=0x7ffffffde320, y=1) at test_fun_passing.f90:17
#2 0x0000000000400829 in tester () at test_fun_passing.f90:31
#3 0x0000000000400860 in main (argc=1, argv=0x7ffffffde64f) at test_fun_passing.f90:27
#4 0x00007ffffec70830 in __libc_start_main (main=0x40082c <main>, argc=1, argv=0x7ffffffde448, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffffffde438) at ../csu/libc-start.c:291
#5 0x0000000000400669 in _start ()
Этот действительно работает (движетсяf
в свой собственный модуль, но все еще передавая в качестве аргумента), так что это что-то оf
содержащиеся в программе.
module test1
implicit none
contains
subroutine x(ff,y)
interface
real function ff(y)
real, intent(in) :: y
end function ff
end interface
real, intent(in) :: y
integer z
z=ff(y)
end subroutine x
end module test1
module test2
implicit none
contains
real function f(y)
real, intent(in) :: y
write(*,*) y
f=y*y
end function f
end module test2
program tester
use test1
use test2
implicit none
call x(f,1.0)
end program tester
gfortran-7 -ggdb test_fun_passing.f90 -o test && ./test
1.00000000
Проходитf
таким образом, действительный Фортран, или я перешел на некоторые нестандартные функции на родном Linux?