文字字符串的 Fortran 宏函数?
Fortran macro function for literal string?
我需要对各种数据类型名称进行一系列子例程调用。例如:
print*, 'Now giving information about Matrix1'
call mysub(Matrix1, size(Matrix1,1), size(Matrix1,2))
print*, 'About to do function on Matrix1'
call dofunction(Matrix1)
print*, 'Matrix1 is a nice matrix! Huzzah!'
print*, 'Now giving information about Matrix2'
call mysub(Matrix2, size(Matrix2,1), size(Matrix2,2))
print*, 'About to do function on Matrix2'
call dofunction(Matrix2)
print*, 'Matrix2 is a nice matrix! Huzzah!'
print*, 'Now giving information about OtherMat'
call mysub(OtherMat, size(OtherMat,1), size(OtherMat,2))
print*, 'About to do function on OtherMat'
call dofunction(OtherMat)
print*, 'OtherMat is a nice matrix! Huzzah!'
并且我想定义一个宏,它将采用 #define
值,以便我可以包装这个调用序列。例如,定义一个宏mymacro
,我希望能够简单地调用
mymacro(Matrix1)
mymacro(Matrix2)
mymacro(OtherMat)
完成同样的事情。这可能吗?
写一个这样的子程序怎么样:
subroutine mymacro(matrix, matrixName)
! declare matrix, precision should be declare somewhere as a constant
real(precision), dimension(:,:) :: matrix
character(*), intent(in) :: matrixname
print*, 'Now giving information about '//matrixname
call mysub(matrix, size(matrix,1), size(matrix,2))
print*, 'About to do function on '//matrixname
call dofunction(matrix)
print*, matrixname//' is a nice matrix! Huzzah!'
end subroutine mymacro
它并不是为您命名矩阵的确切名称,但足够接近。
mymacro(matrix)
变成
call mymacro(matrix,'matrix')
差别不大,你不觉得吗?
宏本身不是 Fortran 的一部分。大多数(如果不是全部)编译器通过重用 C 预处理器来实现它们。我从这里学到:
https://gcc.gnu.org/onlinedocs/cpp/Macros.html
这可能会奏效:(未测试!)
#define MYSUB(m) write(*,*) "Now giving information about ", #m; \
call mysub(m, size(m,1), size(m,2) ); \
write(*,*) "About to do function on ",#m; \
call dofunction(m) ; \
write(*,*) #m , "is a nice matrix! Huzzah!" ;
请注意,您必须使用适当的编译器标志才能使编译器 运行 成为预处理器。
我花了一段时间才为 gfortran
工作,因为它不支持 #expr
。
想法是使用;
将多个命令放在一行中。当然,这需要禁用通常的行限制。使用 gfortran
,这是通过 -ffree-line-length-0
实现的。
然后,gfortran
的预处理器使用 "x"
而不是 #s
(就像所有其他编译器一样)。
这是结果:它正在处理 ifort
和 gfortran
:
#ifdef __GFORTRAN__
#define mymacro(x) print *, "Now giving information about ", "x" ; \
call mysub( x, size(x,1), size(x,2) ) ; \
print *, "About to do function on ", "x"; \
call dofunction(x) ; \
print *, "x"," is a nice matrix! Huzzah!"
#else
#define mymacro(x) print *, "Now giving information about ", #x ; \
call mysub( x, size(x,1), size(x,2) ) ; \
print *, "About to do function on ", #x; \
call dofunction(x) ; \
print *, #x," is a nice matrix! Huzzah!"
#endif
program main
implicit none
integer :: i(2,2)
i = 123
mymacro(i)
contains
subroutine mysub(ii, N, M)
integer,intent(in) :: ii(:,:), N, M
print *,'in mysub:', ii(1,1)
end subroutine
subroutine dofunction(ii)
integer,intent(in) :: ii(:,:)
print *,'in dofunction:', ii(1,1)
end subroutine
end program main
我需要对各种数据类型名称进行一系列子例程调用。例如:
print*, 'Now giving information about Matrix1'
call mysub(Matrix1, size(Matrix1,1), size(Matrix1,2))
print*, 'About to do function on Matrix1'
call dofunction(Matrix1)
print*, 'Matrix1 is a nice matrix! Huzzah!'
print*, 'Now giving information about Matrix2'
call mysub(Matrix2, size(Matrix2,1), size(Matrix2,2))
print*, 'About to do function on Matrix2'
call dofunction(Matrix2)
print*, 'Matrix2 is a nice matrix! Huzzah!'
print*, 'Now giving information about OtherMat'
call mysub(OtherMat, size(OtherMat,1), size(OtherMat,2))
print*, 'About to do function on OtherMat'
call dofunction(OtherMat)
print*, 'OtherMat is a nice matrix! Huzzah!'
并且我想定义一个宏,它将采用 #define
值,以便我可以包装这个调用序列。例如,定义一个宏mymacro
,我希望能够简单地调用
mymacro(Matrix1)
mymacro(Matrix2)
mymacro(OtherMat)
完成同样的事情。这可能吗?
写一个这样的子程序怎么样:
subroutine mymacro(matrix, matrixName)
! declare matrix, precision should be declare somewhere as a constant
real(precision), dimension(:,:) :: matrix
character(*), intent(in) :: matrixname
print*, 'Now giving information about '//matrixname
call mysub(matrix, size(matrix,1), size(matrix,2))
print*, 'About to do function on '//matrixname
call dofunction(matrix)
print*, matrixname//' is a nice matrix! Huzzah!'
end subroutine mymacro
它并不是为您命名矩阵的确切名称,但足够接近。
mymacro(matrix)
变成
call mymacro(matrix,'matrix')
差别不大,你不觉得吗?
宏本身不是 Fortran 的一部分。大多数(如果不是全部)编译器通过重用 C 预处理器来实现它们。我从这里学到: https://gcc.gnu.org/onlinedocs/cpp/Macros.html
这可能会奏效:(未测试!)
#define MYSUB(m) write(*,*) "Now giving information about ", #m; \
call mysub(m, size(m,1), size(m,2) ); \
write(*,*) "About to do function on ",#m; \
call dofunction(m) ; \
write(*,*) #m , "is a nice matrix! Huzzah!" ;
请注意,您必须使用适当的编译器标志才能使编译器 运行 成为预处理器。
我花了一段时间才为 gfortran
工作,因为它不支持 #expr
。
想法是使用;
将多个命令放在一行中。当然,这需要禁用通常的行限制。使用 gfortran
,这是通过 -ffree-line-length-0
实现的。
然后,gfortran
的预处理器使用 "x"
而不是 #s
(就像所有其他编译器一样)。
这是结果:它正在处理 ifort
和 gfortran
:
#ifdef __GFORTRAN__
#define mymacro(x) print *, "Now giving information about ", "x" ; \
call mysub( x, size(x,1), size(x,2) ) ; \
print *, "About to do function on ", "x"; \
call dofunction(x) ; \
print *, "x"," is a nice matrix! Huzzah!"
#else
#define mymacro(x) print *, "Now giving information about ", #x ; \
call mysub( x, size(x,1), size(x,2) ) ; \
print *, "About to do function on ", #x; \
call dofunction(x) ; \
print *, #x," is a nice matrix! Huzzah!"
#endif
program main
implicit none
integer :: i(2,2)
i = 123
mymacro(i)
contains
subroutine mysub(ii, N, M)
integer,intent(in) :: ii(:,:), N, M
print *,'in mysub:', ii(1,1)
end subroutine
subroutine dofunction(ii)
integer,intent(in) :: ii(:,:)
print *,'in dofunction:', ii(1,1)
end subroutine
end program main