总之,是否可以通过使用关联访问Fortran模块中定义的预处理器指令?
上下文
我使用预处理程序语句来定义子例程以打印警告和错误消息。例如,我在文件errors.f
中使用以下模块/子例程来打印警告消息
module errors
use, intrinsic :: iso_fortran_env, only : error_unit=>stderr
implicit none
contains
!> Print formatted warning message.
subroutine warn_print( file, line, mesg )
implicit none
character(len=*), intent(in) :: file
integer, intent(in) :: line
character(len=*), intent(in) :: mesg
write(stderr,'(a,a,a,i4,a,a)') "WARNING::", file, ":", line, ": ", mesg
end subroutine warn_print
end module errors
并且,在单独的文件errors.h
中,我use
以上模块并定义预处理器宏
use errors
#define warn( text )warn_print(__FILE__,__LINE__,text)
然后我#include
文件errors.h
在我希望使用警告打印例程的任何文件/模块中,这样我就可以简单地写
call warn("Some warning message")
并且编译器将自动包含调用警告消息的文件和行号。
问题
#include 'errors.h'
在Fortran代码中的使用相当特殊,它隐藏了use
模块的errors
。理想情况下,我更愿意在错误模块本身中定义上述预处理器。但是,当使用该模块时,此预处理器指令不可用于use
此模块的程序/模块。
有没有办法通过使用关联来访问预处理器指令?
我能想到的唯一另一种方法是在调用编译器时使用errors模块并定义预处理器指令(例如,使用带有ifort的-D
标志)。任何有关实现上述目标的替代方法的建议都将不胜感激。
答案 0 :(得分:2)
不,这根本不可能,因为预处理和编译阶段是完全独立的,C预处理器对Fortran USE语句一无所知。
我在大多数.F90来源中使用#include'config.h'(来自autoconf),没有问题。
答案 1 :(得分:1)
这可能不是你想要的,但如果你正在使用ifort,你可以使用追溯功能来实现类似的东西(更强大,但也更丑陋),例如。
program tracetest
call sub(5)
write(*,*) '=== DONE ==='
end program tracetest
subroutine sub(n)
use ifcore
integer :: n
character(len=60) :: str
write(str,*) '=== TROUBLE DETECTED: n =',n ! code -1 means "do not abort"
call tracebackqq(str,-1)
end subroutine sub
然后,使用-traceback
进行编译,以查看源文件,行和堆栈跟踪。由于内联,堆栈跟踪和线可能会模糊;为了避免这种情况,您可以指定-traceback -O0
来获得这样的smth:
=== TROUBLE DETECTED: n = 5
Image PC Routine Line Source
a.out 0000000000473D0D Unknown Unknown Unknown
a.out 0000000000472815 Unknown Unknown Unknown
a.out 0000000000423260 Unknown Unknown Unknown
a.out 0000000000404BD6 Unknown Unknown Unknown
a.out 0000000000402C14 sub_ 12 tracetest.f90
a.out 0000000000402B18 MAIN__ 2 tracetest.f90
a.out 0000000000402ADC Unknown Unknown Unknown
libc.so.6 000000323201EC5D Unknown Unknown Unknown
a.out 00000000004029D9 Unknown Unknown Unknown
=== DONE ===
或者,如果想要保持优化,并且还想查看正确的行(12),则可以使用(例如)-fast -traceback -debug all,inline_debug_info
进行编译。其他编译器可能会提供类似的东西,但我不确定。