Fortran Coder

查看: 220|回复: 4

[子程序] 不能传递子程序名字

[复制链接]

3

帖子

1

主题

0

精华

新人

F 币
30 元
贡献
15 点
发表于 2021-12-13 21:41:04 | 显示全部楼层 |阅读模式
env:ubuntu 20.04+ifort
CODE:
[Fortran] 纯文本查看 复制代码
program  main
  CALL B()
  CALL FKB(B)


contains
   subroutine B()
   IMPLICIT NONE
   write (*,*) 'fk'
   end subroutine B

   subroutine FKB(fcn)
   implicit none
   INTERFACE
      SUBROUTINE fcn()
      IMPLICIT NONE
      END SUBROUTINE fcn
   END INTERFACE
   write (*,*) '1'
   call B()
   write (*,*) '2'
   call fcn()
   write (*,*) '3'
   end subroutine FKB

end

很简单的程序,把子程序名字‘B' 通过'fcn'传递给子程序'FKB'里,编译也不报错,但是运行以后发现

ifort -g main.F90
./a.out

fk
1
fk
2
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC                Routine            Line        Source
a.out              000000000040490A  Unknown               Unknown  Unknown
libpthread-2.31.s  00007F86D9BE53C0  Unknown               Unknown  Unknown
Unknown            00007FFFF6983F50  Unknown               Unknown  Unknown


显然调用'fcn'的时候出现了问题。
请问这到底是为什么?如何解决?


回复

使用道具 举报

3

帖子

1

主题

0

精华

新人

F 币
30 元
贡献
15 点
 楼主| 发表于 2021-12-13 22:05:19 | 显示全部楼层
或者有人能帮我试着跑一下可以么,看看报不报错

164

帖子

0

主题

0

精华

版主

World Analyser

F 币
380 元
贡献
333 点

新人勋章美女勋章元老勋章热心勋章规矩勋章管理勋章

QQ
发表于 2021-12-14 08:28:18 | 显示全部楼层
gfortran处理主程序contains下的函数有特殊的方式。
你把 subroutine B 放到 program 外面去就行了,或者放到一个module里。

另外的问题,建议用 Procedure 代替子程序内的 interface

[Fortran] 纯文本查看 复制代码
Module fcnMod
  Interface
    Subroutine IF_fcn()
    End Subroutine IF_fcn
  End Interface
contains
   subroutine B()
     write (*,*) 'fk'
   end subroutine B
End Module fcnMod

program  main
  use fcnMod
  IMPLICIT NONE

  CALL B()
  CALL FKB(B)
  
contains

   subroutine FKB(fcn)
     Procedure(IF_fcn) :: fcn
     write (*,*) '1'
     call B()
     write (*,*) '2'
     call fcn()
     write (*,*) '3'
   end subroutine FKB
   
end

或者
[Fortran] 纯文本查看 复制代码
Subroutine C()
  write (*,*) 'fc'
End Subroutine C

program  main
  IMPLICIT NONE
  Interface
    Subroutine IF_fcn()
    End Subroutine IF_fcn
  End Interface
  Procedure(IF_fcn) :: C
  CALL C()
  CALL FKB(C)
  
contains

   subroutine FKB(fcn)
     Procedure(IF_fcn) :: fcn
     write (*,*) '1'
     call C()
     write (*,*) '2'
     call fcn()
     write (*,*) '3'
   end subroutine FKB
   
end

3

帖子

1

主题

0

精华

新人

F 币
30 元
贡献
15 点
 楼主| 发表于 2021-12-14 19:37:32 | 显示全部楼层
非常有启发性的建议。
实际上我写的东西是一个鲍威尔寻路解非线性方程组的MODULE,所以必须要传递函数名字。
MODULE里面再加MODULE,这个我不确定,但是的确提供了一种思路。
至于用Procedure去替代interface 我都没想过。。。。
太感谢你了,我好好鼓捣鼓捣

164

帖子

0

主题

0

精华

版主

World Analyser

F 币
380 元
贡献
333 点

新人勋章美女勋章元老勋章热心勋章规矩勋章管理勋章

QQ
发表于 2021-12-15 08:26:31 | 显示全部楼层
不需要module里再加module,在module里(而不是program)就行。可以在同一个module,或者另一个module。

Fortran 应该是不允许module里再写module的。但是module允许有SubModule
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2022-1-19 15:20

Powered by Tencent X3.4

© 2013-2022 Tencent

快速回复 返回顶部 返回列表