Concatenating an expanded macro and a word using the Fortran preprocessor

别等时光非礼了梦想. 提交于 2019-11-27 08:17:45

问题


I'm trying to concatenate a word in the source code with the expansion of a preprocessor macro. Basically I have foo somewhere in the code, and with a #define EXPANSION bar I want to obtain foobar. However, I'm struggling to find a way to do this, which works with all compilers. For the moment I would be happy if it works with gfortran and ifort.

According to its documentation, the gfortran preprocessor is a C preprocessor running in "traditional mode", which does not have the ## token paste operator. However, the same effect can be obtained with an empty C-style /**/ comment. The ifort preprocessor seems to behave more like the normal C preprocessor, so normal token pasting does the trick in ifort. Unfortunately the empty /**/ comment does not work in ifort, as the comment is replaced by a single space instead.

Here is a little example:

#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#define PASTE(x,y) x ## y

foo/**/EXPANSION   
CAT(foo,EXPANSION)

For which gfortran produces:

foobar
foo ## bar

While ifort gives me:

foo bar
foobar

Of course I could choose the right way by checking the predefined macros for both compilers:

#ifdef __GFORTRAN__
foo/**/EXPANSION
#else
CAT(foo,EXPANSION)
#endif

This works for both of them, but it's rather ugly to have the preprocessor conditional for every expansion. I would much rather avoid this and have some macro magic only once in the beginning.

I have seen this answer to another question, which would probably allow me to work around this issue, but I would rather find a solution that does not invoke the preprocessor separately.

I'm not too familiar with the C preprocessor. Maybe there is a simple way to do what I want. Any ideas?

EDIT: I've already tried something like this:

#define EXPANSION bar
#define CAT(x,y) PASTE(x,y)
#ifdef __GFORTRAN__
#define PASTE(x,y) x/**/y
#else
#define PASTE(x,y) x ## y
#endif

CAT(foo,EXPANSION)

Unfortunately this does not work in gfortran where it produces fooEXPANSION. I'm not entirely sure how this works, but apparently the expansion of the CAT macro prevents the expansion of EXPANSION in the same line. I suspect that this is a feature of the "traditional" C preprocessor ...


回答1:


I have done some research and it seems that basically most Fortran compilers (i.e. Intel and PGI) use a relatively normal C-preprocessor with a token pasting operator. We only need a special treatment for gfortran, which uses a C preprocessor in traditional mode without a token pasting operator.

Thanks to an entry on c-faq.com I found this definition of a CAT macro that works with all compilers I tested so far:

#ifdef __GFORTRAN__
#define PASTE(a) a
#define CAT(a,b) PASTE(a)b
#else
#define PASTE(a) a ## b
#define CAT(a,b) PASTE(a,b)
#endif

Another solution (that still uses the /**/ trick) was posted by Jonathan Leffler in this answer to a related question.



来源:https://stackoverflow.com/questions/41243555/concatenating-an-expanded-macro-and-a-word-using-the-fortran-preprocessor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!