drl*_*mon 9 debugging profiling fortran
在Fortran中是否可以查询我所在的函数或子例程的名称?即,我应该代替'???' 让它在屏幕上打印'my_subroutine'?
subroutine my_subroutine()
write(*,*) ???
end subroutine my_subroutine
Run Code Online (Sandbox Code Playgroud)
我试图找到一种方法来实现自定义调试器/分析器,只使用文本编辑器的搜索和替换机制.以编程方式查询我在代码中的位置会很有帮助.
您可以使用预处理器打印出文件名和行号.您可能希望利用预定义的预处理器符号__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)
这可能会产生您正在寻找的效果,特别是如果您只为每个文件编写一个子例程.