首页 > 解决方案 > 子程序可以包含在 Fortran 的子程序(而不是程序)中吗?

问题描述

我必须处理一个用 Fortran 编写的旧软件(主要是在 70 年代编写的,并且在 3 年前维护得很差)。

我正在尝试使用 VS2017 和英特尔 oneAPI 编译器(Fortran Compiler Classic 2021.3.0)为 64 位架构编译它。

在更新其中一个模块的过程中,我说服自己编译器不支持我所学到的被称为子例程之间的“主机关联”(通过 CONTAINS 语句)。包含子例程中定义的符号似乎在包含的子例程中都不可见(如果我在包含的子例程中使用 IMPLICIT NONE ,编译器会告诉我我需要声明所有这些符号,而如果我不这样做,编译器会得到声明非常错误并且与包含子程序中的声明不匹配。打印了许多误导性错误消息)。

你们中的某个人能否确认是这种情况或提供编译器选项以启用过去某些编译器明确允许的此功能?如果需要,我会发布源代码(我不会立即发布它,因为我认为这对于 Fortran 专家来说可能是一个非常幼稚的问题,而我完全是个新手)。

真挚地,

在这里,我按照评论中的要求补充原始帖子

原始代码:

Subroutine LoadUserLibs(TypesInDeck,*) 

... OMITTED COMMENTS ...

! This routine is only used in the multi-DLL configuration (otherwise empty routine)

!dec$ if defined (TRNSYS_MULTI_DLL)

 Use DFWIN
 Use DFLIB
 !Use KERNEL32
 Use TrnsysConstants
 Use TrnsysFunctions
 Use TrnsysData, Only: steamMethod,isNISTSteamFound

! Force explicit variable declaration
 Implicit None
! Local variable declarations
 Type(T_WIN32_FIND_DATA):: WFD
 Character (len=maxPathLength) UserDir,FoundListStr,SearchListStr
 Character (len=maxMessageLength) msgString
 Integer :: libFile, j, k
 Logical :: bSt
 Character (len=12) jStr,TypeNum,numDLLsStr
 Character (len=20) routineName
 Integer luw !listing file logical unit number
 Integer (kind=8) ExistTest !declares an integer to temporarily contain a pointer
 Integer i !not used but must be delcared as part of a POINTER declaration.
 Integer (kind=8) LibHandles(100) !declares an array where handles to loaded libraries are stored.
 Integer LibCount !a counter variable used to keep track of how many dlls have been loaded
 Integer TypeCount !a counter variable used to count how many Types were found in a given dll.
 Integer TypesInDeck(nMaxUnits) !an array containing a list of Types that are in the deck being run.
 Integer TotalTypes/0/ !the total number of Types in the deck being run (no duplicates)
 Integer TypesListed/0/ !a variable used to count how many of the Types that were found, have been listed so far.
 Integer, Allocatable :: SearchList(:,:) !an array of Type numbers to look for in dlls.
 Integer, Allocatable :: FoundList(:)
 Logical :: isType155InDeck = .false., isType155DllFound = .false.
! Common black definitions
 Integer(INT_PTR_KIND()) paa(nMaxTypes)  !declares an integer array that will contain pointer addresses to the Types
 Integer(INT_PTR_KIND()) saa  !declares an integer that will contain a pointer address of the NIST steam routines.
 Common /USRDLLS/ paa,saa
! Pointer definitions
 Pointer (p,i)

... OMITTED CODE ...

!dec$ else
   ! Single-DLL configuration: empty routine
!dec$ endif

 Return

Contains

Subroutine LoadTypesFromDll()

... OMITTED CODE ...

End Subroutine LoadTypesFromDll

End Subroutine LoadUserLibs

我在编译原始代码时收到的错误:

Severity    Code    Description Project File    Line    Suppression State
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   276 
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   284 
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   303 
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   309 
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   314 
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   315 
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   317 
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.   [CFILENAME]       C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   302 
Error       error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.   [CFILENAME]       C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   308 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   276 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   284 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   284 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   303 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   309 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   314 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   315 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   315 
Error       error #6362: The data types of the argument(s) are invalid.   [TRIM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   317 
Error       error #6410: This name has not been declared as an array or a function.   [FOUNDLIST]       C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   291 
Error       error #6410: This name has not been declared as an array or a function.   [LIBHANDLES]      C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   268 
Error       error #6423: This name has already been used as an external function name.   [PAA]      C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   289 
Error       error #6423: This name has already been used as an external function name.   [SEARCHLIST]       C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   292 
Error       error #6460: This is not a component name that is defined in the encompassing structure.   [CFILENAME]      C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   283 
Error       error #6514: Substring or array slice notation requires CHARACTER type or array.   [CFILENAME]      C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   302 
Error       error #6514: Substring or array slice notation requires CHARACTER type or array.   [CFILENAME]      C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   308 
Error       error #6514: Substring or array slice notation requires CHARACTER type or array.   [FOUNDLIST]      C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   321 
Error       error #6514: Substring or array slice notation requires CHARACTER type or array.   [TYPENUM]        C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   284 
Error       error #6515: This function, which is specified as the left side of an assignment statement, is invalid.   [PAA]     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   289 
Error       error #6515: This function, which is specified as the left side of an assignment statement, is invalid.   [SEARCHLIST]      C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   292 
Error       error #6535: This variable or component must be of a derived or structure type.   [WFD]     C:\Development\trndll-vs2017-ifc\TRNDLL\SourceCode\Kernel\Userlib.f90   283 

标签: visual-studio-2017fortrancontainssubroutineintel-oneapi

解决方案


内部过程(在 a 之后CONTAINS)可以看到在“主机范围”(在 之前CONTAINS)声明的所有实体,并且可以看到其他内部过程,但看不到在其他内部过程中声明的实体。主机关联只上树。例如:

subroutine outer
integer :: X
...
contains
subroutine innerA
real :: A
end subroutine innerA
subroutine innerB
real :: B
end subroutine innerB
end subroutine outer

子例程outer可以看到innerA和的显式接口innerBinnerA并且innerB可以看到彼此和变量的显式接口X,但是innerA看不到innerB's variable BinnerB也看不到innerA's variable A

我怀疑您描述的行为是否得到其他编译器的支持。鉴于您说它是在 70 年代编写的,它不可能使用从 Fortran 90 开始的模块。我的猜测是您的“更新模块之一”引入了错误。


推荐阅读