2012-02-07 73 views
3

总之,是否可以通过使用关联访问在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。理想情况下,我宁愿在错误模块本身中定义上述预处理器。但是,在使用该模块时,此预处理器指令不适用于此模块的程序/模块。

有没有一种方法可以通过使用关联来访问预处理指令?

我能想到的唯一方法就是在调用编译器时使用错误模块并定义预处理器指令(例如,使用ifort的-D标志)。对于实现上述任何替代方法的任何建议将不胜感激。

回答

2

不,这是不可能的,因为预处理和编译阶段完全相互独立,C预处理器不知道任何有关Fortran USE语句的内容。

我使用#include'config.h'(来自autoconf)在我的大多数.F90源代码中,没有问题。

+0

我以为这么多,这就是为什么我使用我在我的问题中描述的设置。我希望得到其他人的关于实现一个函数的不同方案的建议,这个函数会打印它被调用的文件和行号。欢迎来到So! – Chris 2012-02-07 19:23:54

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得到水木清华这样的:

=== 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。其他编译器中可能有类似的东西,但我不确定。

+0

Thanks @laxxy - 我对此一无所知。这是一个很好的答案,但不幸的是不便携。看看是否有这个功能的等效/相似便携版本会很有趣。 – Chris 2012-02-09 13:21:59