2012-02-07 57 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