在gfortran中使用宏连接字符串

4

在使用gfortran的Mac系统上,连接(##)的C预处理宏似乎不起作用。在其他系统上使用其他Fortran编译器可以正常运行,因此我正在寻找gfortran的解决方法。我必须使用##来创建许多变量,因此我不能没有它们。

示例代码:

#define CONCAT(x,y) x##y
program main
   integer, parameter:: CONCAT(ID,2) = 3
   print*,"Hello", ID_2
end program main

在 MAC 上使用 gfortran 进行编译时出现编译错误。
gfortran m.F90 -o m
m.F90:5.23:
integer, parameter:: ID##2 = 3
                       1
Error: PARAMETER at (1) is missing an initializer

通常的策略是先将文件传递给预处理器,然后编译预处理后的文件:https://dev59.com/m5nga4cB1Zd3GeqPedqm#38953582 - ewcz
1
gfortran 配置了 tradcpp(gcc -E -traditional)以避免 c99 // 注释和 Fortran 连接之间的冲突。如上所述,一个典型的替代方案是通过 Makefile 显式地使用不同的预处理器。 - tim18
1个回答

6

##在gfortran中无法使用(不仅限于Mac OS),因为其以传统模式运行CPP。

根据gfortran邮件列表中的讨论,在传统模式下正确的运算符是x/**/y,因此您需要区分不同的编译器:

#ifdef __GFORTRAN__
#define CONCAT(x,y) x/**/y
#else
#define CONCAT(x,y) x ## y
#endif

其他人(http://c-faq.com/cpp/oldpaste.html)使用这种形式,当一个宏被传递给CONCAT(通过使用Fortran预处理器连接扩展宏和单词)时,它的表现更好:

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

间接的表达方式有助于在字符串连接之前扩展传递的宏(在此之后为时已晚)。

1
感谢你把我带到这里,@VladimirF。我正在看你的第二个代码示例,不应该是#define PASTE(a,b) a ## b吗?也就是说,在PASTE的定义中添加b作为参数? - chw21

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接