Fortran查询和打印输出函数或子例程名称

drl*_*mon 9 debugging profiling fortran

在Fortran中是否可以查询我所在的函数或子例程的名称?即,我应该代替'???' 让它在屏幕上打印'my_subroutine'?

subroutine my_subroutine()
   write(*,*) ???
end subroutine my_subroutine
Run Code Online (Sandbox Code Playgroud)

我试图找到一种方法来实现自定义调试器/分析器,只使用文本编辑器的搜索和替换机制.以编程方式查询我在代码中的位置会很有帮助.

Ste*_*ini 10

不,你不能.你想要实现的是被称为反射,它在Fortran中不可用(在C或C++中也不重要).


Yan*_*ann 7

您可以使用预处理器打印出文件名和行号.您可能希望利用预定义的预处理器符号__LINE____FILE__.这是一个例子:

预处理器宏在头文件中定义(以便它可以在多个位置使用),称之为errormsg.h:

#define ERRORMSG(msg) write(0,'("There was an error at ",I4," in file ",/,A,/,"Error message: ",A)') __LINE__,__FILE__,msg
Run Code Online (Sandbox Code Playgroud)

然后,您可以在程序,库或模块文件中包含此头文件,例如:

#include "errormsg.h"

program main 

  ERRORMSG("not really an error...")
  call foo()

end program


subroutine foo()

  ERRORMSG("not an error too!")

end subroutine
Run Code Online (Sandbox Code Playgroud)

ERRORMSG("not really an error...")似乎是fortran代码的奇怪语法,但它被c-preprocessor替换为使用宏定义.因此,当编译它时,它看起来像:

write(0,'("There was an error at ",I4," in file ",/,A,/,"Error message: ",A)') __LINE__,__FILE__,"not really an error"
Run Code Online (Sandbox Code Playgroud)

对于我的ERRORMSG宏,我选择使用0文件单元打印到stderr.你显然可以随心所欲地编写消息,只要它能产生语法正确的FORTRAN代码.

要编译它需要您将标志传递给编译器,它们与编译器略有不同.这对我有用,例如:

gfortran -cpp -o errorTest errorTest.f90
Run Code Online (Sandbox Code Playgroud)

也就是说,对于gfortran,-cpp在编译之前调用c预处理器.上述程序的输出如下所示:

There was an error at    5 in file 
errorTest.f90
Error message: not really an error...
There was an error at   13 in file 
errorTest.f90
Error message: not an error too!
Run Code Online (Sandbox Code Playgroud)

这可能会产生您正在寻找的效果,特别是如果您只为每个文件编写一个子例程.