预处理器和使用关联
Posted
技术标签:
【中文标题】预处理器和使用关联【英文标题】:Preprocessors and use association 【发布时间】:2012-02-28 17:37:51 【问题描述】:总而言之,是否可以通过使用关联访问在 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 代码中的使用相当特殊,它隐藏了 errors
模块的 use
。理想情况下,我更愿意在错误模块本身中定义上述预处理器。但是,当使用该模块时,此预处理器指令不适用于 use
s 此模块的程序/模块。
有没有办法通过使用关联使预处理器指令可访问?
我能想到的唯一其他方法是只使用错误模块并在我对编译器的调用中定义预处理器指令(例如,使用带有 ifort 的 -D
标志)。任何关于实现上述任何替代方法的建议将不胜感激。
【问题讨论】:
【参考方案1】:不,这根本不可能,因为预处理和编译阶段是完全分开的,而且 C 预处理器对 Fortran USE 语句一无所知。
我在我的大多数 .F90 源代码中都使用 #include 'config.h'(来自 autoconf),没有问题。
【讨论】:
我想了很多,这就是为什么我使用我在问题中描述的设置。我希望获得其他人对不同方案的建议,以实现打印调用它的文件和行号的函数。欢迎来到 So!【参考方案2】:这可能不是你想要的,但如果你使用 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
来获得这样的信息:
=== 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
进行编译。其他编译器中可能有类似的东西,但我不确定。
【讨论】:
谢谢@laxxy - 我对此一无所知。这是一个很好的答案,但不幸的是不便携。看看是否有此功能的等效/类似便携式版本会很有趣。以上是关于预处理器和使用关联的主要内容,如果未能解决你的问题,请参考以下文章