pgf90 Preprocessor incompatibility

Hye all,

I need to add such directives in my Fortran code :

#define FS(X) fs_##X##


which should replace for example:
FS(name)
with
fs_name

This is (I think) standard with C/C++ preprocessor, but is not accepted with :
pgf90 -Mpreprocess

Any tips ??
thanks

labrach from Toulouse, France

Bonjour labrach,

Unfortunately, the Fortran preprocessor doesn’t support the “##” syntax. However, the C/C++ preprocessor does, so if you don’t mind adding a preprocessing step to your build, you can do the following:

pgcc -Mcpp FortranFile.F -i FortranFile.f
pgf90 -c FortranFile.f

Hope this helps,
Mat

Unfortunately, it’s not so easy :(

pgcc -Mcpp FortranFile.F -o FortranFile.f
(or pgf90 -Mcpp)

changes my fortran lines such than

^^^^^^do 10 i=1,2
10^^^^continue

into
^^^^^^do 10 i=1,2
10^continue

which is not standard f77

thank’s
labrach

Try adding “-Mfree” to the pgf90 compilation line or change the extension to “f90” to use the free instead of fixed format.

  • Mat

pgcc -Mcpp FortranFile.F90 -o FortranFile.f90

Hello Mat,

I can’t use the free format option Mfree because it’s NOT a free fromat (it is f77 with some dynamic extensions):

  • commentary lines start with C in first column,
  • continuation line have a character in 5th column,

and then the pgf90 -Mfree -c myfile.f can not compile

The question is : why the pgcc -Mcpp is modifying the source lines with no pragma ???
I’m very confused with this preprocessor …

any other tip ??

labrach

I think we’re stuck, at least for now. I’ve put a request in with engineering to add an option to pgprepro (our preprocessor which is envoked with -Mcpp) to disable whitespace collapsing. This is necessary for C but obviously not good if you want to preprocess Fortran with a fixed format. I’ve also requested that they update the pgf90 internal preprocessor so it can handle “##”. But, I’m not sure if this can done.

Sorry I couldn’t find a work around.

  • Mat

Try this:

Compiler option: pgf90 -Mcpp test.F
It should give test.f as an output. Note that there is only one pair of ##.

…test.F…

#define CX(X) kk_##X

subroutine CX(abc)
inteter k
do 10 i=1,2
10 continue
CX(k)

end
…end test.F…

…Output test.f…

subroutine kk_abc
inteter k
do 10 i=1,2
10 continue
kk_k

end

Hope this helps.

I’ve too many f77 style fortran subroutines (several hundred of thousand lines !!) and I need to find a solution with preprocessing files without rewriting them (like writing a simple perl preprocessor)

As a remark, I will say that I’m very disapointed with this compiler :

In the next weeks, I will check GNU gfortran as for industrial use

labrach

I think you will have trouble finding a standard preprocessor that takes the syntax you have. The latest C spec specifically talks about the C preprocessor, and says:

Merging of tokens to form new tokens in Standard C is controlled by the presence of a merging operator, ##, in macro definitions. … ## must not appear at the beginning or end of a replacement list…

Of course, Fortran has nothing to say about a preprocessor standard…

Hi labrach,

I did some research and found a solution. Instead of using “##” to concatentate do the following:

#define FS(X) fs_/**/X

The C style comments are removed after the “X” variable is replaced, thus causing the concatentation.

As for your other concerns. I believe Brent has found a soultion to your multiple python module issue and has posted a reponse to your previous post. (See here).

Fortran 90 compatability between major releases is a concern of us as well. Unfortunately in order continue advances in optimizations, we sometimes do need break compatability. However, since most Fortran libraries are written in F77, if you compile your libraries with pgf77 instead, you should not need to recompile.

We do appreciate your comments. Understanding our customers needs and helping them meet their goals is greatly important to us.

Thanks,
Mat

Great !!!


The /**/ can be used successfully instead of ## with pgf90 -Mpreprocess

Dealing with compilers, preprocessors, linker is a whole story (the one of my working life !!) when doing porting : we actually use fortran with c/c++ with python on solaris,irix64,hp-ux11,linux,aix1, …)

Thank’s a lot to both of you (I’m also replying to brentl in the other post)

laurent

I realize this is an extremely old post, but the solution to use ‘/**/’ in place of ‘##’ does not work for our case.

We have in our code a section that has the following defines:

#define CONCAT3(op,T,D) op##T##D
#define GET_VAR(T,D) CONCAT3(get_var_,T,D)
#define GET_VAR_D0 GET_VAR(NF_TYPE, D0)

The preprocessor in pgf90 (version 11.1.0) will leave the following:

#define NF_TYPE int
interface nfu_get_var
   module procedure GET_VAR_D0
end interface

as:

interface nfu_get_var
   module procedure get_var_##int## D0
end interface

However, if I use ‘pgf90 -Mcpp’ the output is correct.

interface nfu_get_var
   module procedure get_var_intD0
end interface

Why is there a disconnect between the using ‘pgf90 -Mcpp’, and the standard pgf90 preprocessor (or ‘pgf90 -F’ and even ‘pgf90 -E’)? Also, is there a way to not do the ‘pgf90 -Mcpp’ first followed by the actual pgf90 compile?

Why is there a disconnect between the using ‘pgf90 -Mcpp’, and the standard pgf90 preprocessor

Legacy reasons. -Mcpp uses the C preprocessor, while the default is to use a Fortran preprocessor that takes into account Fortran issues (such as Fixed format).

  • Mat