Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 使用宏替换Fortran子例程名称_Macros_Fortran - Fatal编程技术网

Macros 使用宏替换Fortran子例程名称

Macros 使用宏替换Fortran子例程名称,macros,fortran,Macros,Fortran,我正在编写一个允许用户记录信息的模块。我想提供一个记录字符串消息的接口,它可以被称为 call m_log(msg) 因此,在文件m_logger.f90中,我将 module m_logger .. subroutine m_log(msg) .. end module program main use m_logger call m_log(msg) end program 在main.f90文件中,用户将拥有 module m_logger .. subroutin

我正在编写一个允许用户记录信息的模块。我想提供一个记录字符串消息的接口,它可以被称为

call m_log(msg)
因此,在文件m_logger.f90中,我将

module m_logger
..
  subroutine m_log(msg)
  ..
end module 
program main
use m_logger

call m_log(msg)
end program 
在main.f90文件中,用户将拥有

module m_logger
..
  subroutine m_log(msg)
  ..
end module 
program main
use m_logger

call m_log(msg)
end program 
现在,我如何用
调用m\u日志(msg、\uu文件、\uu行)
替换
调用m\u日志(msg)

由于这种替换,将调用记录器模块中不同的子例程
子例程m_log(msg,filename,linenum)

如果我使用像
#define m_log(msg)m_log(msg,_FILE_uuu,_LINE_u)
这样的宏,则必须将它添加到使用记录器的每个用户文件中


另外,我不想强制用户显式地传递
\uuuuuuuuuuuuuuuuuuuuuuuuuu文件

我有办法做到这一点吗?或者还有其他的选择吗

提前谢谢

编辑: 我讨论了comp.lang.fortran。添加链接以供参考。

如果您不想显式地强制执行
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu文件和
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

subroutine m_log(msg, filename, linenum)
   character(len=*) :: msg
   character(len=*), optional :: filename
   integer, optional :: linenum
   if(present(filename)) then
      <something with filename>
   endif
   if(present(linenum)) then
      <something with linenume>
   endif
   <normal stuff with msg>
end subroutine
子程序m_日志(消息、文件名、行数)
字符(len=*)::msg
字符(len=*),可选::文件名
整数,可选::linenum
如果(存在(文件名)),则
恩迪夫
如果(存在(linenum)),则
恩迪夫
结束子程序

如果
filename
linenum
附加了任何值,则内部函数返回真值,否则返回假值。

在这种情况下,必须使用C使用的相同方法。定义您建议的宏

 #define log(msg) m_log(msg,__FILE__,__LINE__)
在一个单独的文件中(可能与其他有用的宏一起),并使用
#include“file.inc”
将其包括在内(标准Fortran include不够)


如果宏的名称与其实际调用的子例程不同,则可以确保用户必须使用include,并且不能忘记它。

由于希望用户将它们作为编译器宏传递,因此首先必须为宏选择不同的名称<代码>文件>和
都是预定义的宏。这两个宏由预处理器定义,而不是由用户传递。我想这可能会引起一些混乱

如果希望允许用户通过编译器选项选择性地提供宏,则最好在子程序中包含
#ifdef
指令:

subroutine m_log(msg)
  implicit none
  character(len=*) :: msg
  character(len=something) :: file
  integer ::line
  !Initialize file and line to some default value
  file=...
  line=...
#ifdef __KVM_FILE__
   file=__KVM_FILE__
#endif
#ifdef __KVM_LINE__
   line=__KVM_LINE__
#endif
   ...

这样,用户将始终使用相同的语法调用子例程
call m_log(something)
,但效果将根据编译宏而变化。当然,这也需要用户在每次更改此宏时重新编译代码。如果这样做成本太高,您可以设置一个带有可选参数的子例程(如Kyle的回答),然后将
#define
宏包含在
#ifdef
块中,并将它们放入.h文件中,让您的用户始终包含该文件。(类似于弗拉基米尔的回答)

这并不能解决我的问题。如果用户没有传递可选参数,我就没有文件名和linenum。那我就误解了你写的内容。我唯一的建议是强烈建议用户在
msg
中包含子例程/文件名和行号,并且只使用一个
m_log
子例程。您能在这里添加一些说明或示例吗?我很困惑。基本上,我该如何用
m\u log(msg,\uuu文件,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?当您说您不希望用户显式地传递参数时,您的意思是用户将把它们定义为环境变量或宏,而不是将它们放在函数调用中吗?
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
是编译器宏。