Fortran SAVE 语句

2024-01-06

我读过有关save(英特尔)语言参考文档中的声明,但我不太明白它的作用。有人可以用简单的语言向我解释一下当save语句包含在模块中?


原则上,当模块超出范围时,该模块的变量将变为未定义 - 除非使用 SAVE 属性声明它们,或者使用 SAVE 语句。 “未定义”意味着如果您再次使用该模块,则不允许您依赖具有先前值的变量 - 当您重新访问该模块时它可能具有先前的值,也可能不会 - 没有保证。但许多编译器不这样做module变量——变量可能保留它们的值——编译器不值得花精力去弄清楚模块是否仍在范围内,并且模块变量可能被视为全局变量——但不要依赖于此!为了安全起见,请在主程序中使用“保存”或“使用”模块,这样它就不会超出范围。

“保存”在过程中也很重要,用于存储子例程或函数调用之间的“状态”(由@ire_and_curses编写)——“第一次调用”初始化、计数器等。

subroutine my_sub (y)

integer :: var
integer, save :: counter = 0
logical, save :: FirstCall = .TRUE.

counter = counter + 1

write (*, *) counter

if (FirstCall) then
   FirstCall = .FALSE.
   ....
end if

var = ....

etc.

在此代码片段中,“counter”将报告子例程 x 的调用次数。尽管实际上在 Fortran >=90 中可以省略“保存”,因为声明中的初始化意味着“保存”。

与模块情况相反,对于现代编译器,如果没有保存属性或声明初始化,过程的局部变量在调用过程中丢失其值是正常的。因此,如果您尝试在稍后的调用中使用“var”,然后在该调用中重新定义它,则该值是未定义的,并且可能不是在该过程的先前调用中计算的值。

这与许多 FORTRAN 77 编译器的行为不同,其中一些编译器保留所有局部变量的值,尽管语言标准并不要求这样做。一些旧程序是根据这种非标准行为编写的——这些程序在较新的编译器上将失败。许多编译器可以选择使用非标准行为并“保存”所有局部变量。

稍后编辑:使用显示的代码示例进行更新不正确使用应该具有 save 属性但没有的局部变量:

module subs

contains

subroutine asub (i, control)

   implicit none

   integer, intent (in) :: i
   logical, intent (in) :: control

   integer, save :: j = 0
   integer :: k

   j = j + i
   if ( control ) k = 0
   k = k + i

   write (*, *) 'i, j, k=', i, j, k

end subroutine asub

end module subs

program test_saves

   use subs
   implicit none

   call asub ( 3, .TRUE. )
   call asub ( 4, .FALSE. )

end program test_saves

局部变数k子例程的值被故意滥用——在这个程序中,它在第一次调用时被初始化control是 TRUE,但在第二次调用时control是假的,所以k没有被重新定义。但没有保存属性k未定义,因此使用其值是非法的。

用gfortran编译程序,我发现k无论如何保留其价值:

 i, j, k=           3           3           3
 i, j, k=           4           7           7

使用 ifort 和积极的优化选项编译程序,k 失去了它的值:

 i, j, k=           3           3           3
 i, j, k=           4           7           4

使用 ifort 和调试选项,在运行时检测到问题!

 i, j, k=           3           3           3
forrtl: severe (193): Run-Time Check Failure. The variable 'subs_mp_asub_$K' is being used without being defined
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Fortran SAVE 语句 的相关文章

  • 循环变量文件名[重复]

    这个问题在这里已经有答案了 我正在使用 Fortran 对分成许多文件的庞大数据集进行计算 文件的名称是 maltoLyo12per reimage set1 traj maltoLyo12per reimage set2 traj mal
  • C++/Fortran 中贝塞尔函数的集成 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 如何在 Fortran 或 和 C 中对包含贝塞尔函数的方程进行从 0 到 无穷大 的数值积分 我在matlab中做了 但对于较大的输入和特
  • 忽略 doxygen 注释块中的行

    是否可以在 doxygen 注释块中包含将被 doxygen 忽略的内容 换句话说 我们可以在 doxygen 评论块中发表评论吗 背景 我们正在将 Fortran 项目的代码内注释转换为 doxygen 可解析的格式 但是该项目要求代码内
  • Fortran 读取混合字符串和数字数据

    我在读取语句时遇到问题 我更喜欢 Fortran90 尽管如果有帮助的话其他版本也是可能的 我的文件中有一堆数据行 可以描述为 以空格分隔 没有固定的格式 包含一个字符串 后跟 7 个数字 字符串包含正斜杠 这是一个例子 maxele OS
  • 如何使用模块向 Fortran 公开 Python 回调

    这个 scipy 文档页面 http docs scipy org doc numpy dev f2py python usage html call back arguments关于 F2Py 指出 回调函数 也可以在模块中显式设置 然后
  • 在 Fortran 中读取行数已知但每行条目数未知的数据文件

    如何读取包含已知行数但每行中的条目数未知的数据文件 例如如果我的数据文件包含类似的内容 1 3 4 5 6 7 8 9 1 3 5 6 4 5 6 7 8 3 5 6 7 8 4 5 7 8 即三行 但每行中的数据未知 有一次我需要来自一行
  • 使用 Visual Studio 2013 和 Intel Fortran 编译混合 C++/C 代码

    我正在尝试编译一个简单的 C Fortran 混合程序 但存在链接问题 我使用的是Visual Studio 2013 Ultimate和Intel Visual Fortran Compiler XE 14 该程序非常简单 是从网上的某个
  • 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
  • Dependency Walker 未显示所有依赖的 Dll

    我有一个 fortran dll 我想知道它所依赖的程序集再分配目的 http software intel com en us forums showthread php t 73161 我发现的一件事是依赖项步行器没有显示所有依赖项 即
  • fortran中双引号和单引号的区别?

    我刚刚开始使用 Fortran 对双引号和单引号的使用感到困惑 它们是等价的 它们的用法没有区别 您可以使用它来打印引号字符之一 print print 首先打印 进而 注意 您还可以在一行中使用两个引号字符来打印一个 print prin
  • Fortran if stop 需要 endif 吗?

    在 fortran 90 中 if stop 语句是否需要结束 endif example if foo eq 1 stop do some stuff do some stuff 是循环的一部分还是 stop 意味着程序结束时 endif
  • 关于for循环中的fortran continue语句的问题

    我正在分析 Fortran 代码并有一个简单的问题 我想知道下面代码中 100 和 200 处的 继续 语句的作用 它会增加 i 和 j 计数器吗 如果是这样的话 不会if not flg 那么条件包含flg循环中 flg 的 最后一个值
  • 如何在 conda 中静音或抑制 gfortran (或 clang?)后端?

    我一直致力于构建一个非常特殊的 conda 环境 专为python and R与串扰使用rpy2 我想出的方法可以安装正确的R包如下 install main environment sh now date T echo Start Tim
  • 在一条语句中对多个变量进行相同的赋值

    有没有一种方法可以为不同的变量分配相同的值 而无需在单个语句中构造数组 例如 如果我有变量a b c d and e 我可以分配类似的东西吗 a b c d e 10 0 我知道我可以用一行来做 a 10 0 b 10 0 c 10 0 d
  • 尝试读取名单后返回的状态不是预期的

    我想从文件中读取名单 但在名单不存在的情况下实现捕获选项 从我读到的here http msg ucsf edu local programs IBM Compilers Fortran html pgs lr76 htm我期望状态为 84
  • R:使用带有 .Call 和 C/C++ 包装器的 Fortran 子例程而不是 .Fortran 的优点?

    我有一个 R 包 它使用大量 Fortran 子例程来进行递归线性代数计算的嵌套循环 很大程度上依赖于 BLAS 和 LAPACK 例程 作为 Fortran 的接口 我使用 Fortran功能 我刚刚读过乔纳森卡拉汉的博客文章 http
  • Python 读取未格式化的直接访问 Fortran 90 给出不正确的输出

    这是数据的写入方式 它是一个二维浮点矩阵 我不确定大小 open unit 51 file rmsd nn output form unformatted access direct status replace recl Npoints
  • 使用 MacLaurin 展开的 Fortran Sine 函数的微小差异

    我正在用 Fortran 创建一个程序 它接受以弧度表示的 sin x 的 x 然后是要计算的项数 这是我的程序 Sine value using MacLaurin series program SineApprox implicit n
  • Fortran的性能

    Fortran 的表现计算机语言基准游戏 http shootout alioth debian org 出奇的糟糕 今天的结果显示 Fortran 在两项四核测试中分别排名第 14 和第 11 在单核测试中排名第 7 和第 10 现在 我

随机推荐