Fortran可变参数宏中的CPP / GPP(加上Fortran //连接)

时间:2016-12-26 19:15:31

标签: fortran c-preprocessor variadic

我正在尝试编译一个巨大的,世界着名的数值天气预报代码 - 主要使用Fortran 90编写 - 广泛使用 cpp ,并成功地与PGI,Intel和gfortran一起使用。现在,我继承了一个专家已经添加了几百个可变参数宏的版本。他们使用英特尔和 fpp ,这可能是以Fortran为中心的,并且可以让它全部运行起来。我需要使用gfortran,并且无法使用 cpp 来处理此代码及其新增功能。

问题的严重简化如下 -

预处理代码:

    PRINT *, "Hello" // "Don"
#define adderv(...) (myadd(__VA_ARGS__))
    sumv = adderv(1, 2, 3, 4, 5)

使用不带-traditional选项的 cpp 将处理可变参数宏,但不会处理Fortran串联:

$ cpp -P t.F90
    PRINT *, "Hello"
    sumv = (myadd(1, 2, 3, 4, 5))

另一方面,使用-traditional标志处理串联,但不处理可变参数宏:

$ cpp -P -traditional t.F90 
t.F90:2:0: error: syntax error in macro parameter list
 #define adderv(...) (myadd(__VA_ARGS__))
 ^
    PRINT *, "Hello" // "Don"
    sumv = adderv(1, 2, 3, 4, 5)

我真的很难找到一种方法来促进两者的处理。

我开始玩 gpp ,感觉我已经接近了,但事实是我可能还有很长的路要走。它不接受...,也不会展开__VA_ARGS__。当然,以下不再是变量宏了......

    PRINT *, "Hello" // "Don"
#define adderv() (myadd(__VA_ARGS__))
    sumv = adderv(1, 2, 3, 4, 5)



$ gpp t.F90
    PRINT *, "Hello" // "Don"
    sumv = (myadd(__VA_ARGS__))

我已经在网上搜索无济于事了,到目前为止我看到的最好的可能性,让我觉得可能是丑陋和痛苦,是将我所有的Fortran连接操作符分成不同的行。即。

PRINT *, "Hello" // "Don"

变为

PRINT *, "Hello" /&
&              / "Don"

cpp和gpp的内部对我来说有点吓人,但如果有人看到成功的可能性并且可能指出我正确的方向,我会非常感激。重构这个庞大的代码实际上不是一个选择,尽管如果我非常绝望,自动化策略(例如将那些连接操作符拆分为单独的行)可能是。

其他信息 - roygvib建议我尝试添加-C标志。我们最近一直在压制它,因为它似乎在Fortran代码中引入了许多C注释。好吧,我继续尝试这个,我想我离我更近了:

$ cat t.f90
        PRINT *, "Hello" // "Don"
    #define adderv(...) (myadd(__VA_ARGS__))
        sumv = adderv(1, 2, 3, 4, 5)

当我使用-P和-C标志调用时,它自然会通过C ++(Fortran concat运算符),但它似乎也会生成一些C注释的版权文本:

   $ /lib/cpp -P -C  t.F90
   /* Copyright (C) 1991-2014 Free Software Foundation, Inc.
      This file is part of the GNU C Library.
   .
   .
   .
   /* wchar_t uses ISO/IEC 10646 (2nd ed., published 2011-03-15) /       Unicode 6.0.  */
   /* We do not support C11 <threads.h>.  */
       PRINT *, "Hello" // "Don"
       sumv = (myadd(1, 2, 3, 4, 5))

一些研究(Remove the comments generated by cpp)表明,版权的增加可能是cpp的一个相对较新的“特征”。

我看不到任何简单的方法来抑制它,所以我想我可能需要构建一个如上所述调用cpp的包装器脚本(例如 mycpp ),过滤掉任何C-样式注释,然后将其传递到下一阶段。

这不是最优的,我有点怀疑,因为整个包中也包含C代码。但从理论上讲,我认为最糟糕的事情是未能在预处理的C代码中生成注释。

如果有人知道如何简单地抑制该版权信息的产生,我可能会开展业务。

1 个答案:

答案 0 :(得分:1)

至少在下面描述的简单示例的上下文中,我通过安装较旧的cpp来解决问题。 Other research已确认版本4.8在预处理的Fortran代码中插入了额外的C注释,这显然不是一件好事。解决方案很简单,使用cpp-4.7。

安装(在Ubuntu 16.04上)比我预期的更简单。一个简单的

sudo apt-get install cpp-4.7
put the necessary executable in /usr/bin/cpp-4.7

并按照我想要的方式预处理以下示例。

$ /usr/bin/cpp-4.7 -C -P t.F90
    PRINT *, "Hello" // "Don"
    sum = (myadd(1, 2, 3, 4, 5))