使用 GNU gfortran 字符串化宏

2024-02-02

如何使用 GNU gfortran 字符串化预处理器宏?我想将宏定义传递给 GNU gfortran,然后将其用作代码中的字符串。

实际上我想这样做:

program test
implicit none
character (len=:), allocatable :: astring
astring = MYMACRO
write (*, *) astring
end program test

然后构建:

gfortran -DMYMACRO=hello test.F90

我尝试创建各种宏,例如:

#define STRINGIFY_(x) #x
#define STRINGIFY(x) STRINGIFY_(x)
...
astring = STRINGIFY(MYMACRO)

但这不适用于 gfortran 预处理器。

我还尝试使用不同风格的宏:

#define STRINGIFY(x) "x"
...
astring = STRINGIFY(MYMACRO)

但这只是创建一个包含文本“MYMACRO”的字符串。

然后我尝试将宏定义更改为:

-DMYMACRO=\"hello\"

但这在构建过程中引起了不相关的问题。

感谢您的帮助


您尝试使用众所周知的 C 预处理器字符串化配方, 即:

#define STRINGIFY_(x) #x
#define STRINGIFY(x) STRINGIFY_(x)

失败有两个原因,每个原因本身就足够了。

首先也是最简单的,您显然尝试在其中使用它的源文件 有扩展名.f90。此扩展名的含义是什么gfortran(并 GCC 编译器驱动程序(任何其他名称)是:不应进行预处理的自由格式 Fortran 源代码。相似地.f95, .f03 and .f08。如果你想gfortran推断出一个来源 文件包含自由格式的 Fortran 代码must进行预处理,给它之一 扩展.F90, .F95, .F03 or .F08. See GCC 文档 这几点 https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html#Overall-Options

然而,即使你做了那么简单的事情,第二个原因也很重要。

使用 C 预处理器来预处理 Fortran 源代码与 C 一样古老 (虽然很老,但比 Fortran 年轻得多)。gfortran有义务不 打破古老的工作密码;因此,当它调用 C 预处理器时, 它在中调用它传统模式. The 传统模式C 预处理器的 是预处理器在第一次标准化之前的行为方式 C 语言(1989),只要非标准化行为可以被确定。在传统的 模式下,预处理器无法识别字符串化运算符“#”,这是 由第一个 C 标准引入。您可以通过调用预处理器来验证这一点 直接喜欢:

cpp -traditional test.c

where test.c包含一些使用字符串化方法的尝试。这 尝试失败。

你不能哄gfortran独自工作字符串化配方。

但有一个解决方法。您可以调用cpp直接,不受传统模式的束缚, 预处理要在其中完成字符串化的 Fortran 源代码并中继其 输出到gfortran。如果您已经知道这一点并且正在寻找gfortran-独自的 您无需进一步阅读解决方案。

以这种方式在测试源中进行字符串化将如下所示:

cpp -std=c89 '-DSTRINGIFY_(x)=#x' '-DSTRINGIFY(x)=STRINGIFY_(x)' '-DMYMACRO=STRINGIFY(hello)' test.f90

其输出是:

# 1 "test.f90"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.f90"
program test
implicit none
character (len=:), allocatable :: astring
astring = "hello"
write (*, *) astring
end program test

该输出就是您想要编译的内容。您也可以通过以下方式实现这一点:

cpp -std=c89 '-DSTRINGIFY_(x)=#x' '-DSTRINGIFY(x)=STRINGIFY_(x)' \
'-DMYMACRO=STRINGIFY(hello)' test.f90 > /tmp/test.f90 \
&& gfortran -o test /tmp/test.f90

然后你会发现./test存在并且执行它输出hello.

您可以通过进一步细化消除中间临时文件。您的 F90 来源 代码将编译为 F95,因为后者比前者保守。所以你可以采取 这样做的好处是,如果 你告诉它你正在管道的语言,使用它-x language选项。这 您可以通过这种方式指定的 Fortran 方言是f77, f77-cpp-input, f95 and f95-cpp-input,其中-cpp-input前缀表示 源将被预处理,它的缺失表示它没有被预处理。因此

cpp -std=c89 '-DSTRINGIFY_(x)=#x' '-DSTRINGIFY(x)=STRINGIFY_(x)' \
'-DMYMACRO=STRINGIFY(hello)' test.f90 |  gfortran -x f95 -o test -

与之前的解决方案一样工作,减去临时文件,并发出 无害的警告:

Warning: Reading file '<stdin>' as free form

(注意并保留最后的 - 在命令行上。这就是告诉我们的gfortran到 编译标准输入。)。的含义-x f95带来了额外的 经预处理的经济来源cpp, 没有经过预处理 再次由编译器执行。

选项的使用-std=c89当调用cpp呼吁警惕 解释。它具有使cpp符合最早的C标准。 那是接近-traditional我们可以在仍然利用的同时得到#- 运算符,字符串化配方取决于它,但有了它你就可以拥抱 打破的可能性someFortran 代码(如果您以这种方式预处理它); 否则gfortran本身不会强制执行-traditional。如果是 你的测试程序,你可以安全地省略-std=c89,允许cpp来确认 构建时遵循默认的 C 标准。但如果你允许或指示它 符合-std=c99或稍后,标准将强制认可 的//作为单行注释的开头(按照 C++),其中任何行 包含串联运算符的 Fortran 语言将在 第一次出现。

当然,如果您使用 are usingmake或另一个构建系统来构建 您想要字符串化宏的代码,您将有一种方法来告诉 构建系统什么动作构成编译给定的可编译类 文件。对于任何 Fortran 源文件fsrc你想编译 字符串化序言,指定的操作将是这样的:

cpp -std=c89 '-DSTRINGIFY_(x)=#x' '-DSTRINGIFY(x)=STRINGIFY_(x)' \
'-DMYMACRO=STRINGIFY(hello)' fsrc.f90 | gfortran -x f95 -c -o fsrc.o -
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 GNU gfortran 字符串化宏 的相关文章

  • 为什么我必须在 Fortran 中隐式指定函数的双精度返回值?

    我是 Fortran 新手 我正在尝试common堵塞 我的代码很简单 program main implicit double precision p real 8 x y common yvalue y x 3d0 y 3d0 prin
  • HTML 预处理器?

    是否有一个 HTML 预处理器可以进行类似的简单页面处理服务器端包括 http en wikipedia org wiki Server Side Includes 但是生成一组静态 HTML 页面 我认为它们被称为预处理器 http ht
  • SELECT TYPE 构造中的多态性分配

    我试图定义一个分配不同类型数组的子例程 这是代码的简化版本 subroutine Allocation1 Vec class allocatable intent out Vec select type Vec type is real 8
  • 循环变量文件名[重复]

    这个问题在这里已经有答案了 我正在使用 Fortran 对分成许多文件的庞大数据集进行计算 文件的名称是 maltoLyo12per reimage set1 traj maltoLyo12per reimage set2 traj mal
  • 忽略 doxygen 注释块中的行

    是否可以在 doxygen 注释块中包含将被 doxygen 忽略的内容 换句话说 我们可以在 doxygen 评论块中发表评论吗 背景 我们正在将 Fortran 项目的代码内注释转换为 doxygen 可解析的格式 但是该项目要求代码内
  • 提高由整数商定义的变量的精度

    假设我有以下程序 program derp implicit none integer parameter ikind selected real kind 18 real kind ikind a 2 0 3 0 print a end
  • Fortran 中指数函数的 DEXP 或 EXP?

    我有两个非常简短的问题 1 我刚刚读到DEXP is the archaic的形式EXP 这是否意味着不应再使用它 我一直以为DEXP 双精度等于EXP 2 指数函数的范围是多少 它依赖于编译器吗 问题 1 在现代 Fortran 中 最好
  • 链接到遗留库:-lgfortranbegin from a premade makefile

    我在尝试编译由一些研究人员开发的程序时遇到了一些麻烦 该程序应该以非常精确的方式计算傅立叶变换和其他一些有用的操作科学论文在这里 https www researchgate net profile Gerard Gomez2 public
  • 使用 Fortran (CLFORTRAN) 在 OpenCL 中将两个选项作为参数传递

    当我的主机程序采用 C 语言时 我可以传递两个选项作为 OpenCL 函数的参数 例如 我可以通过两个 标志到clCreateBuffer像这样的函数 clCreateBuffer context CL MEM READ ONLY CL M
  • OpenMP 因大型数组而崩溃

    我正在使用 Fortran 和 OpenMP 但当我尝试在存在大型数组时使用 OpenMP 并行化循环时 我不断遇到问题 例如 以下代码 PROGRAM main IMPLICIT NONE INTEGER PARAMETER NUMLOO
  • 将 C 字符串数组传递给 Fortran (iso_c_binding)

    如何传递 C 字符串数组 char cstrings 到 Fortran 子程序 问题使用 iso c binding 的 fortran C 桥接器中的字符串数组 https stackoverflow com questions 968
  • Fortran:向文件添加列(即跳过不同数量的水平空格)

    我是 Fortran f90 的初学者 一些看似简单的问题结果却导致严重头痛 感谢您帮助我解决这个问题 我的代码运行一个循环 处理数据并将它们写入文件 我希望将这些数据写入同一文件的列中 直到循环完成 OPEN unit 11 file f
  • 可变格式

    我编写了一个程序来计算平方有限差分矩阵 您可以在其中输入行数 等于列数 gt 这存储在变量矩阵中 该程序运行良好 program fin diff matrix implicit none integer dimension allocat
  • 将预处理器宏添加到 xcode 6 中的目标

    也许这非常简单 但我找不到在 Xcode 6 中为目标定义预处理器宏的方法 我已经做了一个屏幕截图来显示它在 Xcode 中的位置 因为它更容易 选择项目文件 选择您想要的目标 转到构建设置 搜索 预处理器 添加用于调试 发布或两者的预处理
  • 如何禁用 C++ 宏中的警告

    在 Visual C 中 您可以使用 pragma 暂时禁用警告 pragma warning suppress 4307 如何禁用宏内的警告 例如 当我导致如下所示的 积分常量溢出 警告时 define TIMES A MILLION x
  • Fortran 函数:指针作为实际参数,目标作为形式

    我正在尝试破译 Fortran 代码 它将指向函数的指针作为实际参数传递 而形式参数则是目标 它在主程序中定义并分配一个 globalDATA 类型的指针 然后调用一个传递该指针的函数 module dataGLOBAL type glob
  • Javascript:stringify对象(包括类型函数的成员)

    我正在寻找一种解决方案来跨浏览器将 Javascript 对象序列化 和反序列化 为字符串 包括恰好是函数的对象成员 一个典型的对象看起来像这样 color red doSomething function arg alert Do som
  • 如何在 Fortran 90 中迭代包含数字、单词和空格的字符串?

    文件说明 STL文件由以下部分组成 solid
  • 如何将mortran代码转换为fortran代码

    我有一些 Mortran 代码 来自 glmnet 我想阅读和编译 我知道在编译时 Mortran首先转换为Fortran 然后编译 如果有预处理器的话 如何安装 Mortran 预处理器 特别是 OS X 上的 Mortran3 我在以下
  • Python 读取未格式化的直接访问 Fortran 90 给出不正确的输出

    这是数据的写入方式 它是一个二维浮点矩阵 我不确定大小 open unit 51 file rmsd nn output form unformatted access direct status replace recl Npoints

随机推荐