Fortran 子模块 - 无法打开模块文件 »mod_globals.smod«

Fortran Submodules - Can't open module file »mod_globals.smod«

我开始编写一个按模块组织的小 Fortran 程序。每个模块都包含用于分配和释放的初始化和完成子例程。

现在我得到了模块 globals 中名为 "Abort" 的子例程的循环依赖。如果发生错误,该子例程应调用每个模块的 finalize 子例程。 "Abort"子程序的调用经过一些计算后放在所有模块中。

我的计划是使用 Fortran 2008(2003) 引入的子模块。但它并没有解决问题。我对子模块功能的理解有误吗?

我的 Fortran 编译器告诉我:

Can't open module file »mod_globals.smod« for reading at (1): No such file or directory

这是模块全局变量的一部分:

! Module Globals
MODULE MOD_GLOBALS
    IMPLICIT NONE
    PRIVATE

    INTERFACE
        MODULE SUBROUTINE doAbort()
        END SUBROUTINE doAbort
    END INTERFACE

CONTAINS

    SUBROUTINE setAbortFlag(fileString,errorLine)
        ... fill variables with the fileString and errorLine
        CALL doAbort()
    END SUBROUTINE setAbortFlag

END MODULE MOD_GLOBALS

! Submodule 
SUBMODULE (MOD_GLOBALS) S_MOD_GLOBALS
    IMPLICIT NONE

CONTAINS

    MODULE PROCEDURE doAbort
        USE MOD_TEST, ONLY: finalizeTEST

        CALL finalizeTEST()

        EXIT(-1)
    END PROCEDURE doAbort

END SUBMODULE S_MOD_GLOBALS

这里是测试模块的相应代码部分:

! Module Test
MODULE MOD_TEST
    IMPLICIT NONE
    PRIVATE
    PUBLIC finalizeTEST, doSomeStuff

CONTAINS

    SUBROUTINE finalizeTEST()
        ... do some deallocations
    END SUBROUTINE finalizeTEST

    SUBROUTINE doSomeStuff()
        USE MOD_GLOBALS, ONLY: setAbortFlag

        ... maybe error in some calculations
        CALL setAbortFlag(__FILE__,__LINE__)
    END SUBROUTINE doSomeStuff

END MODULE MOD_TEST

更多的是评论而不是答案,但是评论框提供的格式化方式太少了...

如果您删除 PRIVATE 语句,您的代码将顺利编译。我无法将其跟踪到标准,而且我对子模块的经验有限,所以我不确定这种行为是否正确。然而 the gfortran documentation 表示

Submodules are supported. It should noted that MODULEs do not produce the smod file needed by the descendent SUBMODULEs unless they contain at least one MODULE PROCEDURE interface. The reason for this is that SUBMODULEs are useless without MODULE PROCEDUREs. See http://j3-fortran.org/doc/meeting/207/15-209.txt for a discussion and a draft interpretation. Adopting this interpretation has the advantage that code that does not use submodules does not generate smod files.

我怀疑 PRIVATE 导致接口不是来自模块的 'exported',因此它不包含任何内容(有用的)并且被前一段中解释的陷阱捕获。添加行

public :: doAbort

还修复了编译问题。

我这里只安装了 gfortran,所以不能用其他编译器测试它。

从你发布的内容来看,我没有看到任何循环依赖问题。