问题的严重简化如下 –
要预处理的代码:
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,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,5)
我真的很难找到一种方法来促进两者的处理.
我开始玩gpp,觉得我已经接近了,但现实是我可能还有很长的路要走.它不接受……而且,它不会扩展__VA_ARGS__.当然,以下不再是一个变量宏了……
PRINT *,"Hello" // "Don" #define adderv() (myadd(__VA_ARGS__)) sumv = adderv(1,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,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,5))
一些研究(Remove the comments generated by cpp)表明,这种版权的增加可能是cpp的一个相对较新的“特征”.
我看不出任何简单的方法来抑制它,所以我想我可能需要构建一个如上所述调用cpp的包装脚本(例如mycpp),过滤掉任何C风格的注释,然后将其传递给下一个阶段.
它不是最优的,我有点怀疑,因为整个包也有C代码.但从理论上讲,我认为最糟糕的事情是未能在预处理的C代码中生成注释.
如果有人知道如何简单地抑制版权信息的产生,我可能会在商业中.
解决方法
安装(在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,5))