Types 模块和类型绑定过程

Types 模块和类型绑定过程,types,fortran,Types,Fortran,我收到以下错误消息: The name of the module procedure conflicts with a name in the encompassing scoping unit. [ADD_SUB] 在ubuntu12.0464位平台上使用ifort 12.0.3编译下面的源代码时 有什么想法吗 Module Header Type :: hello Integer :: a Integer :: b Integer

我收到以下错误消息:

The name of the module procedure conflicts with a name
in the encompassing scoping unit.   [ADD_SUB]
ubuntu12.04
64位平台上使用
ifort 12.0.3
编译下面的源代码时

有什么想法吗

Module Header

  Type :: hello

      Integer :: a
      Integer :: b    
      Integer :: sum

    contains

      procedure, pass :: add => add_sub

  End type hello

  Interface

    Subroutine add_sub(this)
       Import hello
       Implicit None
       class(hello) :: this

    End Subroutine add_sub

  End Interface

End Module


Module Routines

  use Header

contains

  Subroutine add_sub(this)    
    Implicit None    
    class(hello), intent(inout) :: this
    this%sum=this%a+this%b    
  End Subroutine

End Module



Program Test

  use Header    
  use Routines

  Implicit None

  Type(hello) :: x

  x%a=1    
  x%b=2

  call x%add()

  write(*,*) x

End Program Test

您已经定义了两次例程
add_sub
,并且名称相互冲突。这可以通过在模块
标题的开头添加以下行来轻松解决:

private add_sub

这使得
add\u sub
的定义成为模块的私有定义,因此导入模块的任何例程都无法直接访问该定义-相反,它们将通过公共接口
add
访问该定义。您已经定义了例程
add\u sub
两次,并且名称相互冲突。这可以通过在模块
标题的开头添加以下行来轻松解决:

private add_sub

这使得
add_sub
的定义成为模块的私有定义,因此导入模块的任何例程都无法直接访问它-相反,它们将通过公共接口
add
访问它。我认为您的问题是,由于Fortran编译器为所有模块过程提供了一个显式接口,因此编译器会在程序
test
的最顶层范围内找到
add\u sub
的两个实例

我已经看过Fortran 2003标准,但无法立即找到禁止您所做操作的规则。然而,这是不寻常的。将例程声明和定义放在单独的编译单元中的冲动似乎比普通的Fortran程序员更困扰C/C++程序员

如果您确实想在编码中分离这些,我认为您有以下选项:

  • 将您的子例程定义放入不是模块的编译单元中。例如,我可以通过删除模块
    routines
    并将子例程
    add\u sub
    放在自己的编译单元中来编译程序片段
  • 使用
    include
    语句包含定义例程的源文件的文本
  • 等待编译器实现Fortran 2008的
    子模块
    功能
我并不认为这是一个特别的问题,我是那些普通的Fortran程序员之一,习惯于将类型绑定过程的整个定义与它们绑定到的类型的声明放在同一个编译单元中


请注意,Fortran标准可能并不禁止您执行您正试图执行的操作,但英特尔编译器尚未实现该功能,或未正确实现该功能。为什么不让他们的技术支持人员来运行这个呢,他们通常都很好。

我认为你的问题是,因为Fortran编译器为所有模块过程都提供了一个显式接口,编译器在program
test
的最高范围内找到了两个
add\u sub
的实例

我已经看过Fortran 2003标准,但无法立即找到禁止您所做操作的规则。然而,这是不寻常的。将例程声明和定义放在单独的编译单元中的冲动似乎比普通的Fortran程序员更困扰C/C++程序员

如果您确实想在编码中分离这些,我认为您有以下选项:

  • 将您的子例程定义放入不是模块的编译单元中。例如,我可以通过删除模块
    routines
    并将子例程
    add\u sub
    放在自己的编译单元中来编译程序片段
  • 使用
    include
    语句包含定义例程的源文件的文本
  • 等待编译器实现Fortran 2008的
    子模块
    功能
我并不认为这是一个特别的问题,我是那些普通的Fortran程序员之一,习惯于将类型绑定过程的整个定义与它们绑定到的类型的声明放在同一个编译单元中


请注意,Fortran标准可能并不禁止您执行您正试图执行的操作,但英特尔编译器尚未实现该功能,或未正确实现该功能。为什么不让他们的技术支持人员来做呢,他们通常都很好。

谢谢,但没有帮助。直接在“模块头”后面的行中插入“private add_sub”会产生错误消息:“/tmp/ifortqQH46a.o:in function
MAIN_uuu”:Test_1.f90:(.text+0x84):未定义对
add_sub_'/tmp/ifortqQH46a.o:(.rodata+0x18):未定义对“add_sub”的引用。这个程序的特殊性实际上是,类型绑定的程序是在不同于类型的模块中定义的。我在gfortran下测试了这个解决方案,它运行得很好,因此看起来像是编译器依赖的行为。@DaveP:您使用的是什么版本的gfortran?gfortran 4.7.0给出了与ifort类似的
未定义引用
错误(如预期)。谢谢,但没有帮助。直接在“模块头”后面的行中插入“private add_sub”会产生错误消息:“/tmp/ifortqQH46a.o:in function
MAIN_uuu”:Test_1.f90:(.text+0x84):未定义对
add_sub_'/tmp/ifortqQH46a.o:(.rodata+0x18):未定义对“add_sub”的引用。这个程序的特殊性实际上是,类型绑定过程是在不同于类型的模块中定义的。我在gfortran下测试了这个解决方案,它工作得很好,所以看起来像编译器-