预处理器和使用关联

时间:2012-02-07 09:27:31

标签: module preprocessor fortran

总之,是否可以通过使用关联访问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标志)。任何有关实现上述目标的替代方法的建议都将不胜感激。

2 个答案:

答案 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进行编译。其他编译器可能会提供类似的东西,但我不确定。