CPP/GPP 在 Fortran 可变参数宏中(加上 Fortran // 串联)
CPP/GPP in Fortran variadic macro (plus Fortran // concatenation)
我正在尝试编译一个巨大的、世界知名的数值天气预报代码——主要是用 Fortran 90 编写的——广泛使用 cpp,并且成功地使用了 PGI、Intel和 gfortran。现在,我继承了一个版本,其中专家添加了数百个可变参数宏案例。他们使用 Intel 和 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 的内部结构对我来说有点吓人,但如果有人看到成功的潜力并可能为我指出正确的方向,我将非常感激。重组这个庞大的代码确实不是一个选项,但如果我足够绝望的话,自动化策略(例如将那些 concat 运算符分成单独的行)可能是一个选项。
附加信息 - 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 的一个相对较新的 "feature"。
我看不到任何简单的方法来抑制它,所以我想我可能需要构建一个包装脚本(例如 mycpp),如上所述调用 cpp,过滤掉任何 C 风格的注释,然后将其传递到下一阶段。
它不是最佳的,我有点怀疑,因为整个包中也有 C 代码。不过,从理论上讲,我认为最糟糕的情况是无法在预处理的 C 代码中生成注释。
如果有人知道我可以如何简单地抑制该版权消息的生成,我可能会做生意。
至少在下面描述的简单示例的上下文中,我通过安装较旧的 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))
我正在尝试编译一个巨大的、世界知名的数值天气预报代码——主要是用 Fortran 90 编写的——广泛使用 cpp,并且成功地使用了 PGI、Intel和 gfortran。现在,我继承了一个版本,其中专家添加了数百个可变参数宏案例。他们使用 Intel 和 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 的内部结构对我来说有点吓人,但如果有人看到成功的潜力并可能为我指出正确的方向,我将非常感激。重组这个庞大的代码确实不是一个选项,但如果我足够绝望的话,自动化策略(例如将那些 concat 运算符分成单独的行)可能是一个选项。
附加信息 - 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 的一个相对较新的 "feature"。
我看不到任何简单的方法来抑制它,所以我想我可能需要构建一个包装脚本(例如 mycpp),如上所述调用 cpp,过滤掉任何 C 风格的注释,然后将其传递到下一阶段。
它不是最佳的,我有点怀疑,因为整个包中也有 C 代码。不过,从理论上讲,我认为最糟糕的情况是无法在预处理的 C 代码中生成注释。
如果有人知道我可以如何简单地抑制该版权消息的生成,我可能会做生意。
至少在下面描述的简单示例的上下文中,我通过安装较旧的 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))