Fortran OOP模块循环引用致无因编译终止问题求助
问题原因分析
你遇到的编译终止问题确实是模块循环依赖导致的:
sys2_moleculesArray模块必须先引用type3_crossMol_class模块才能定义数组的类型type3_crossMol_class模块的test子程序又需要引用sys2_moleculesArray模块来访问数组
Fortran编译器无法处理这种双向依赖的编译顺序,因此会出现无原因终止的情况。
解决方案
以下是几种能保留类内部子程序结构的可行方案:
方案1:将数组移至类模块内部(最简便)
既然数组是type3_crossMol类的实例集合,逻辑上属于该类的配套数据,直接将其声明在type3_crossMol_class模块的类型定义之后、contains块之前即可,完全消除循环依赖:
module type3_crossMol_class use sys2_paramData use sys2_type3ParamData implicit none type :: type3_crossMol integer(kind=4) :: index,x,y,rotType,checkMol_index integer,dimension(4,2) :: molBondedTo integer,dimension(20) :: potentialNeighMol contains procedure :: initialise => initialise procedure :: addAtom => addAtom procedure :: getPotentialNeigh => getPotentialNeigh procedure :: test => test end type type3_crossMol ! 直接在类模块中声明数组 class(type3_crossMol),dimension(:),allocatable :: type3_crossMol_tagArray contains ... subroutine test(this) use sys2_type3ParamData, only:cur_type3_mol_number implicit none integer :: n class(type3_crossMol):: this do n=1,cur_type3_mol_number print*, "b4 potential",type3_crossMol_tagArray(n)%index end do end subroutine test
这种方案无需额外拆分模块,代码结构也更紧凑,避免了你之前在通用模块中遇到的嵌套问题。
方案2:拆分类型定义与实现(适合大型项目)
如果需要保持数组模块的独立性,可以把类的类型定义单独抽成一个基础模块,让数组模块和类实现模块都依赖这个基础模块,打破循环:
步骤1:创建类型定义模块
module type3_crossMol_def use sys2_paramData use sys2_type3ParamData implicit none ! 仅存放类的类型定义,无过程实现 type :: type3_crossMol integer(kind=4) :: index,x,y,rotType,checkMol_index integer,dimension(4,2) :: molBondedTo integer,dimension(20) :: potentialNeighMol end type type3_crossMol end module type3_crossMol_def
步骤2:修改数组模块
让数组模块仅依赖类型定义模块:
module sys2_moleculesArray use type3_crossMol_def, only: type3_crossMol implicit none class(type3_crossMol),dimension(:),allocatable :: type3_crossMol_tagArray end module sys2_moleculesArray
步骤3:修改类实现模块
让类模块同时依赖类型定义模块和数组模块:
module type3_crossMol_class use type3_crossMol_def use sys2_paramData use sys2_type3ParamData use sys2_moleculesArray implicit none ! 在这里绑定类的过程 contains procedure :: initialise => initialise procedure :: addAtom => addAtom procedure :: getPotentialNeigh => getPotentialNeigh procedure :: test => test ... subroutine test(this) use sys2_type3ParamData, only:cur_type3_mol_number implicit none integer :: n class(type3_crossMol):: this do n=1,cur_type3_mol_number print*, "b4 potential",type3_crossMol_tagArray(n)%index end do end subroutine test
编译时按type3_crossMol_def → sys2_moleculesArray → type3_crossMol_class的顺序执行即可,完全消除循环依赖。
内容的提问来源于stack exchange,提问作者DongAlpha
相关产品推荐
相关产品推荐

