Я хочу написать модуль, перегружающий подпрограмму swap
, которая принимает массив и два индекса и меняет местами два элемента.
Эта подпрограмма должна работать для широкого диапазона массивов, поэтому я хотелчтобы перегрузить его:
module mod_swap
use iso_fortran_env
implicit none
interface swap
module procedure swap_int64, swap_int32, swap_int16, &
swap_real64, swap_real32
end interface swap
public :: swap
private :: swap_int64, swap_int32, swap_int16, &
swap_real64, swap_real32
contains
#define VAR_TYPE real
#define TYPE_KIND real64
#include "swap.inc"
#undef TYPE_KIND
#define TYPE_KIND real32
#include "swap.inc"
#undef TYPE_KIND
#undef VAR_TYPE
#define VAR_TYPE integer
#define TYPE_KIND int64
#include "swap.inc"
#undef TYPE_KIND
#define TYPE_KIND int32
#include "swap.inc"
#undef TYPE_KIND
#define TYPE_KIND int16
#include "swap.inc"
#undef TYPE_KIND
#undef VAR_TYPE
end module mod_swap
с swap.inc
, являющимся:
#define PASTER(x,y) x ## _ ## y
#define EVALUATOR(x,y) PASTER(x,y)
#define SWAP EVALUATOR(swap, TYPE_KIND)
subroutine SWAP(a, i, j)
implicit none
VAR_TYPE(kind=TYPE_KIND), intent(inout) :: a(:)
integer, intent(in) :: i, j
VAR_TYPE(kind=TYPE_KIND) t
t = a(i)
a(i) = a(j)
a(j) = t
end subroutine SWAP
Когда я запускаю gfortran -o test.o -c -cpp test.F90
, он выходит из строя, а когда я запускаю gfortran -E -cpp test.F90
, я выясняю почему:Макрос SWAP
был расширен до swap ## _ ## int16
, а не swap_int16
, как ожидалось.
Однако cpp
напрямую работает:
$ cpp test.F90 > test.f90
$ gfortran -c -o test.o test.f90
После просмотра этого форума и Google в целомЯ пришел к выводу, что проблема заключается в следующем:
Препроцессор работает в традиционном режиме.
И действительно, cpp --traditional
демонстрирует то же поведение, что и gfortran -E -cpp
Итак, вот мои вопросы:
Есть ли лучший способ реализовать эту процедуру, чтобы мне не пришлось повторять одни и те же инструкции только потому, что тип массиваизменился(Обратите внимание, что переменная t
должна иметь тот же тип, что и a
).
Есть ли способ заставить gfortran
использовать нетрадиционный препроцессор?
Если нет, то как мне поступить так, как я хочу, с традиционным препроцессором?