首页 > 解决方案 > 编译时对函数错误的模糊引用

问题描述

所以我有一个fortran .f90 文件(Monte-Carlo 工具的一部分,称为SWEEP),它基本上包含两个主要模块,用于实现使用两种类型的可变长度列表。两个模块如下:

Module LIST_DP_T
Implicit None
Public

Type LIST_DP
    Integer :: Count = 0
    Double Precision, Pointer :: Items(:)
End Type

Interface Assignment(=)
    Module Procedure SetP
End Interface

Interface Operator(+)
    Module Procedure Add
    Module Procedure AddItem
    Module Procedure AddItems
End Interface

Contains

! -------------------------------------------------------

Subroutine Destroy(list)
    ! DESCRIPTION
    !   Clears memory associated with a list type.

    ! ARGUMENTS.
    Type(LIST_DP), Intent(INOUT) :: list

    ! VARIABLES.
    Integer :: err = 0

    ! EXECUTABLE CODE.
    list%Count = 0
    Deallocate(list%Items, STAT=err)
    Nullify(list%Items)
End Subroutine

! -------------------------------------------------------

Subroutine SetP(new, old)
    ! DESCRIPTION
    !   Assigns the list of one list type to another
    !   by passing the list pointer.

    ! ARGUMENTS.
    Type(LIST_DP), Intent(INOUT) :: new
    Type(LIST_DP), Intent(IN)    :: old

    ! EXECUTABLE CODE.
    new%Count = old%Count
    new%Items => old%Items
End Subroutine

! -------------------------------------------------------

Subroutine Copy(new, old)
    ! DESCRIPTION
    !   Copies the list of one list type to another.

    ! ARGUMENTS.
    Type(LIST_DP), Intent(INOUT) :: new
    Type(LIST_DP), Intent(IN)    :: old

    ! EXECUTABLE CODE.
    new%Count = old%Count
    new%Items = old%Items
End Subroutine

! -------------------------------------------------------

Function Add(list1, list2) Result (sumlist)
    ! DESCRIPTION
    !   Adds together two list and
    !   returns a new list.

    ! ARGUMENTS.
    Type(LIST_DP), Intent(IN) :: list1
    Type(LIST_DP), Intent(IN) :: list2
    Type(LIST_DP) :: sumlist

    ! VARIABLES.
    Integer :: err = 0
    Double Precision :: items(list1%Count+list2%Count)

    ! EXECUTABLE CODE.

    ! Save current list.
    If (list1%Count > 0) items(1:list1%Count) = list1%Items
    If (list2%Count > 0) items(list1%Count+1:) = list2%Items

    ! Resize list.
    Deallocate(sumlist%Items, STAT=err)
    sumlist%Count = list1%Count + list2%Count
    Allocate(sumlist%Items(sumlist%Count), STAT=err)

    ! Assign back the list.
    sumlist%Items = items
End Function

! -------------------------------------------------------

Function AddItem(list, item) Result (newlist)
    ! DESCRIPTION
    !   Adds a number to the end of the list and
    !   returns a new list.

    ! ARGUMENTS.
    Type(LIST_DP), Intent(IN)    :: list
    Double Precision, Intent(IN) :: item
    Type(LIST_DP) :: newlist

    ! VARIABLES.
    Integer :: err = 0
    Double Precision :: items(list%Count+1)

    ! EXECUTABLE CODE.

    ! Save current list.
    If (list%Count > 0) items(1:list%Count) = list%Items
    items(list%Count+1) = item

    ! Resize list.
    Deallocate(newlist%Items, STAT=err)
    newlist%Count = list%Count + 1
    Allocate(newlist%Items(newlist%Count), STAT=err)

    ! Assign back the list.
    newlist%Items = items
End Function

! -------------------------------------------------------

Function AddItems(list, items) Result (newlist)
    ! DESCRIPTION
    !   Adds some numbers to the end of the list and
    !   returns a new list.

    ! ARGUMENTS.
    Type(LIST_DP), Intent(IN)    :: list
    Double Precision, Intent(IN) :: items(:)
    Type(LIST_DP) :: newlist

    ! VARIABLES.
    Integer :: err = 0
    Double Precision :: allitems(list%Count+Size(items))

    ! EXECUTABLE CODE.

    ! Save current list.
    If (list%Count > 0) allitems(1:list%Count) = list%Items
    allitems(list%Count+1:) = items

    ! Resize list.
    Deallocate(newlist%Items, STAT=err)
    newlist%Count = list%Count + Size(items)
    Allocate(newlist%Items(newlist%Count), STAT=err)

    ! Assign back the list.
    newlist%Items = allitems
End Function

! -------------------------------------------------------

Double Precision Function SumList(list)
    ! DESCRIPTION
    !   Returns the sum of the list items.
    Type(LIST_DP), Intent(IN) :: list
    SumList = Sum(list%Items)
End Function

End Module

和另一个用于整数列表的模块:

Module LIST_INT_T
Implicit None
Public

Type LIST_INT
    Integer :: Count = 0
    Integer, Pointer :: Items(:)
End Type

Interface Assignment(=)
    Module Procedure SetP
End Interface

Interface Operator(+)
    Module Procedure Add
    Module Procedure AddItem
    Module Procedure AddItems
End Interface

Contains

! -------------------------------------------------------

Subroutine Destroy(list)
    ! DESCRIPTION
    !   Clears memory associated with a list type.

    ! ARGUMENTS.
    Type(LIST_INT), Intent(INOUT) :: list

    ! VARIABLES.
    Integer :: err = 0

    ! EXECUTABLE CODE.
    list%Count = 0
    Deallocate(list%Items, STAT=err)
    Nullify(list%Items)
End Subroutine

! -------------------------------------------------------

Subroutine SetP(new, old)
    ! DESCRIPTION
    !   Assigns the list of one list type to another
    !   by passing the list pointer.

    ! ARGUMENTS.
    Type(LIST_INT), Intent(INOUT) :: new
    Type(LIST_INT), Intent(IN)    :: old

    ! EXECUTABLE CODE.
    new%Count = old%Count
    new%Items => old%Items
End Subroutine

! -------------------------------------------------------

Subroutine Copy(new, old)
    ! DESCRIPTION
    !   Copies the list of one list type to another.

    ! ARGUMENTS.
    Type(LIST_INT), Intent(INOUT) :: new
    Type(LIST_INT), Intent(IN)    :: old

    ! EXECUTABLE CODE.
    new%Count = old%Count
    new%Items = old%Items
End Subroutine

! -------------------------------------------------------

Function Add(list1, list2) Result (sumlist)
    ! DESCRIPTION
    !   Adds together two list and
    !   returns a new list.

    ! ARGUMENTS.
    Type(LIST_INT), Intent(IN) :: list1
    Type(LIST_INT), Intent(IN) :: list2
    Type(LIST_INT) :: sumlist

    ! VARIABLES.
    Integer :: err = 0
    Integer :: items(list1%Count+list2%Count)

    ! EXECUTABLE CODE.

    ! Save current list.
    If (list1%Count > 0) items(1:list1%Count) = list1%Items
    If (list2%Count > 0) items(list1%Count+1:) = list2%Items

    ! Resize list.
    Deallocate(sumlist%Items, STAT=err)
    sumlist%Count = list1%Count + list2%Count
    Allocate(sumlist%Items(sumlist%Count), STAT=err)

    ! Assign back the list.
    sumlist%Items = items
End Function

! -------------------------------------------------------

Function AddItem(list, item) Result (newlist)
    ! DESCRIPTION
    !   Adds a number to the end of the list and
    !   returns a new list.

    ! ARGUMENTS.
    Type(LIST_INT), Intent(IN)    :: list
    Integer, Intent(IN) :: item
    Type(LIST_INT) :: newlist

    ! VARIABLES.
    Integer :: err = 0
    Integer :: items(list%Count+1)

    ! EXECUTABLE CODE.

    ! Save current list.
    If (list%Count > 0) items(1:list%Count) = list%Items
    items(list%Count+1) = item

    ! Resize list.
    Deallocate(newlist%Items, STAT=err)
    newlist%Count = list%Count + 1
    Allocate(newlist%Items(newlist%Count), STAT=err)

    ! Assign back the list.
    newlist%Items = items
End Function

! -------------------------------------------------------

Function AddItems(list, items) Result (newlist)
    ! DESCRIPTION
    !   Adds some numbers to the end of the list and
    !   returns a new list.

    ! ARGUMENTS.
    Type(LIST_INT), Intent(IN)    :: list
    Integer, Intent(IN) :: items(:)
    Type(LIST_INT) :: newlist

    ! VARIABLES.
    Integer :: err = 0
    Integer :: allitems(list%Count+Size(items))

    ! EXECUTABLE CODE.

    ! Save current list.
    If (list%Count > 0) allitems(1:list%Count) = list%Items
    allitems(list%Count+1:) = items

    ! Resize list.
    Deallocate(newlist%Items, STAT=err)
    newlist%Count = list%Count + Size(items)
    Allocate(newlist%Items(newlist%Count), STAT=err)

    ! Assign back the list.
    newlist%Items = allitems
End Function

! -------------------------------------------------------

Integer Function SumList(list)
    ! DESCRIPTION
    !   Returns the sum of the list items.
    Type(LIST_INT), Intent(IN) :: list
    SumList = Sum(list%Items)
End Function

End Module

第三个模块可以在使用模块时使事情变得更容易:

Module LIST_T
    Use LIST_DP_T
    Use LIST_INT_T
    Implicit None
    Public
End Module

然后从名为 Profile_Driver_Input 的不同模块中调用模块 LIST_T,该模块位于不同的 .f90 文件 (profile_driver_input.f90) 中,如下所示:

Module Profile_Driver_Input
Use LIST_T
Use Sweep
Implicit None
Public

Integer, Parameter :: UIN = 102
Integer, Parameter :: MAX_POINTS=1000, MAX_VARS=200

Type Settings
    ! Control parameters.
    Logical :: Solve=.True., PostProcess=.True.
    ! Input files.
    Character(LEN=200) :: MechFile=""  ! Particle mechanism file name.
    Character(LEN=200) :: ChemFile=""  ! Chemistry profile file name.
    ! Time stepping variables.
    Type(LIST_DP)  :: Times  ! Times between PSL outputs (first entry is start time).
    Type(LIST_INT) :: Steps  ! Steps between output times.
....
The code then continues to declare more variables and subroutines. 

编译后,Profile_Driver_Input 模块末尾出现如下错误:

Error: Name 'additem' at (1) is an ambiguous reference to 'additem' from module 'list_dp_t'
Error: Name 'setp' at (1) is an ambiguous reference to 'setp' from module 'list_dp_t'
Error: Name 'setp' at (1) is an ambiguous reference to 'setp' from module 'list_dp_t'
Error: Name 'additem' at (1) is an ambiguous reference to 'additem' from module 'list_dp_t'
Error: Name 'setp' at (1) is an ambiguous reference to 'setp' from module 'list_dp_t'
Error: Name 'setp' at (1) is an ambiguous reference to 'setp' from module 'list_dp_t'
Error: Name 'additem' at (1) is an ambiguous reference to 'additem' from module 'list_dp_t'
Error: Name 'setp' at (1) is an ambiguous reference to 'setp' from module 'list_dp_t'

我似乎无法弄清楚如何解决这个问题。任何帮助/建议将不胜感激。

标签: fortranoverloading

解决方案


您有多个以相同方式命名的符号。它们来自不同的模块,但这仍然是一个问题。例如,additem您显示的两个模块中都存在一个名为的子例程。

如果您实际上不需要调用子例程本身,而只想调用重载运算符 ( +) 和赋值 ( =),则可以将默认可访问性从模块内部更改publicprivate,只保留public实际需要可访问的内容。

如果需要同时从两个模块访问additemanddestroy和其他子例程,则必须将它们重命名为唯一的。例如:additem_list_intadditem_list_dp


推荐阅读