【问题标题】:Procedure pointers in Fortran [duplicate]Fortran 中的过程指针
【发布时间】:2018-11-15 23:50:30
【问题描述】:

我正在尝试拥有一个通用子例程 event() 和一个指向该通用子例程 event_i 的过程指针。然后我想创建任何子例程(如以下代码中的 hello_wolrd)并指向这个创建的子例程。你能帮我理解为什么第一个代码不起作用而第二个代码起作用吗?我在第一个版本的代码中得到的错误是:Program received signal SIGSEGV: Segmentation fault - invalid memory reference。我想使用第一个版本,因为这样我可以在子程序 hello_world 中使用 main 中定义的任何变量,而在第二种情况下,我必须将变量传递给 te 子程序,它不能再被定义为通用子程序 event() , 没有输入。

第一个版本(不工作)

program foo

  implicit none

  interface 
    subroutine event()
    end subroutine event
  end interface

   procedure(event), pointer :: event_i => Null()
   event_i => hello_world
   call event_i

contains

  subroutine hello_world()
    print *, 'hello_world'
  end subroutine

end program foo

第二版(工作):

program foo

  implicit none

  interface 
    subroutine event()
    end subroutine event
    subroutine hello_world()
    end subroutine hello_world
  end interface

   procedure(event), pointer :: event_i => Null()
   event_i => hello_world
   call event_i

end program foo

subroutine hello_world()
  print *, 'hello_world'
end subroutine

我用的是gfortran,编译器版本是

gfortran --version
GNU Fortran (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609

【问题讨论】:

  • 第一个版本不工作(给我分段错误),第二个版本正常工作。对于不清楚的问题,我深表歉意。
  • 欢迎使用 Stack Overflow。 从不“它不起作用”“它不起作用”,真的从不。说出实际发生的事情。它会崩溃吗?它会给出错误的结果吗?它是如何崩溃的?任何错误信息?哪个确切的消息?哪些确切的错误结果以及好的结果应该是什么样子?
  • 你是对的,我们可能没有得到真正的代码。当然,这是一个问题。 @fdevita 请创建一个minimal reproducible example,我们可以自己测试并真正编译。
  • 我已经修复了打印语句中未终止字符的错误,添加了第一个版本给出的错误并指定了编译器版本。
  • 因此,如果需要使用 WSL,似乎必须避免使用 Fortran 2008 的这一特性。根据groups.google.com/d/msg/comp.lang.fortran/6qUqEl8CIoc/… Windows 上的英特尔 Fortran 可能使用不同的机制。此解释适用于 GCC 中的 C 嵌套函数,但对 gfortran stackoverflow.com/a/33357450/721644 仍然有效

标签: pointers fortran procedure windows-subsystem-for-linux


【解决方案1】:

这是一个稍微重要的修改,它与 gfortran 配合得很好:

program foo

  implicit none

  abstract interface 
    subroutine event()
   end subroutine event
 end interface

  procedure(event), pointer :: event_i
  procedure(event), pointer :: event_j


 event_i => hello_world
 event_j => hello_world2

 call event_i
 call event_j


contains

 subroutine hello_world()
    print *, 'hello_world'
 end subroutine


 subroutine hello_world2()
   print *, 'HELLO_WORLD'
 end subroutine

end program foo

【讨论】:

  • 你能解释一下有什么区别,特别是为什么它在问题的版本不起作用的地方有效吗?
  • 我已经尝试过代码,但它给出的分段错误与前一个相同。
  • 我看到的唯一区别是界面上的 ABSTRACT 限定符......我实际上不明白为什么在这种情况下它很重要
猜你喜欢
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多