I was trying to use the C preprocessor for a Fortran program and it
gave me some insight as to why they are always so out of sorts on
comp.lang.c:
C:\gfortran\clf\cpp>type cpp.f90
module mod1
implicit none
intrinsic SYMBOL_1
end module mod1
module mod2
use mod1, only: fun => SYMBOL_1
implicit none
character(*), parameter :: name = #SYMBOL_1
end module mod2
program test
use mod2
implicit none
real x
x = 3
write(*,'(a,f0.6,a,f0.6)') name//'(',x,') = ',fun(x)
end program test
C:\gfortran\clf\cpp>gfortran -x f95-cpp-input -D SYMBOL_1=BESSEL_J0
cpp.f90 -ocp
p
cpp.f90:9.36:
character(*), parameter :: name = #BESSEL_J0
1
Error: Expected an initialization expression at (1)
I found the -x f95-cpp-input command-line option at
http://gcc.gnu.org/onlinedocs/gfortran/Preprocessing-and-conditional-compilation.html#Preprocessing-and-conditional-compilation
And at
http://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#Preprocessor-Options
the -D name=#BESSEL_J0 option. At
http://en.wikipedia.org/wiki/C_preprocessor#Quoting_macro_arguments
we find that #BESSEL_J0 should be replaced by "BESSEL_J0" but
upon examination of compiler output we find that it doesn't work.
Also it fails for ifort:
C:\gfortran\clf\cpp>ifort /Qcpp -D SYMBOL_1=ERFC cpp.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version
9.1
Build 20061104
Copyright (C) 1985-2006 Intel Cor****ation. All rights reserved.
cpp.f90(9) : Error: Invalid radix or character in constant out of radix
range
character(*), parameter :: name = #ERFC
-------------------------------------^
Now we can work around this for gfortran as follows:
C:\gfortran\clf\cpp>type cpp1.f90
module mod1
implicit none
intrinsic SYMBOL_1
end module mod1
module mod2
use mod1, only: fun => SYMBOL_1
implicit none
character(*), parameter :: name = '&
&SYMBOL_1&
&'
end module mod2
program test
use mod2
implicit none
real x
x = 3
write(*,'(a,f0.6,a,f0.6)') name//'(',x,') = ',fun(x)
end program test
C:\gfortran\clf\cpp>gfortran -x f95-cpp-input -D SYMBOL_1=BESSEL_J0
cpp1.f90 -oc
pp1
C:\gfortran\clf\cpp>cpp1
BESSEL_J0(3.000000) = -.260052
But ifort's preprocessor is smart enough to grok a free-form character
continuation context:
C:\gfortran\clf\cpp>ifort /Qcpp -D SYMBOL_1=ERFC cpp1.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version
9.1
Build 20061104
Copyright (C) 1985-2006 Intel Cor****ation. All rights reserved.
Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Cor****ation. All rights reserved.
-out:cpp1.exe
-subsystem:console
cpp1.obj
C:\gfortran\clf\cpp>cpp1
SYMBOL_1(3.000000) = 0.000022
So I ultimately abandoned this C preprocessor nonsense and used
other methods to insert minor edits into my code.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


|