Fortran模块中类型之间的循环依赖 [英] Circular dependency between types in Fortran module

查看:329
本文介绍了Fortran模块中类型之间的循环依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道在Fortran模块中如何完全解决循环依赖关系.以下模块使用ifort-2016和gfortran-4.9编译

I don't know how exactly circular dependencies are resolved in Fortran modules. The following module compiles with ifort-2016 and gfortran-4.9

module types
   implicit none
   type type1
      type(type2), pointer :: t2
   end type type1

   type type2
      type(type1)          :: t1
      integer              :: x
   end type type2
end module

但是如果我将定义顺序更改为

but if I change the definition order to

module types
   implicit none
   type type2
      type(type1)          :: t1
      integer              :: x
   end type type2

   type type1
      type(type2), pointer :: t2
   end type type1
end module

我收到以下错误

error #6457: This derived type name has not been declared.   [TYPE1]
      type(type1)          :: t1

ifort-2016和gfortran-4.9的行为相同. 由于两个模块中都有类似的循环依赖关系,为什么第一个编译而不编译?

the behaviour is the same with ifort-2016 and gfortran-4.9. Since there are similar circular dependencies in both modules why does the first one compile but the second one doesn't?

推荐答案

工作代码与不工作代码之间的区别是类型的位置以及组件的pointer属性.正是这个属性允许类型声明引用以前未定义的类型.

The difference between the working and not-working code is the location of the type with the pointer attribute of the component. It's this attribute that allows a type declaration to refer to a type that has not been previously defined.

看看

type type2
  type(type1)          :: t1
  integer              :: x
end type type2

此处,类型为type2type1组件没有pointer属性.这意味着必须预先定义类型type1.在您的第一个工作示例中,就是这种情况.在第二个例子中,它不是.

Here the type1 component of type type2 hasn't the pointer attribute. That means that the type type1 must have been previously defined. In your first, working, example that is the case. In your second, broken, example, it isn't.

看看其他类型

type type1
   type(type2), pointer :: t2
end type type1

type2组件具有指针属性.因此,在此引用之前不必定义类型type2.您可以在两个示例中看到这一点.

the type2 component has the pointer attribute. So, the type type2 needn't have been defined before this reference. You can see this in action in both examples.

此要求在Fortran 2008标准中表示为

This requirement is stated in the Fortran 2008 standard as

C440(R436)如果未指定POINTER或ALLOCATABLE属性,则component-def-stmt中的clarification-type-spec应指定固有类型或先前定义的派生类型.

C440 (R436) If neither the POINTER nor the ALLOCATABLE attribute is specified, the declaration-type-spec in the component-def-stmt shall specify an intrinsic type or a previously defined derived type.


在这里,我仅将注意力放在pointer属性上.就像引号所示,allocatable属性也是如此.允许以后使用allocatable进行引用是Fortran 2008中的新增功能:在Fortran 2003中,需要pointer属性.正如Vladimir F所评论的那样,并不是在所有编译器中都实现了这种新的自由(它提供了递归可分配的组件).在上面的相应地方阅读"pointerallocatable".


I've restricted attention here to the pointer attribute. As the quote suggests, the same holds with the allocatable attribute. Allowing this later reference with allocatable is new in Fortran 2008: in Fortran 2003 the pointer attribute was required. As Vladimir F comments, this new freedom (which provides for recursive allocatable components) is not implemented in all compilers. In the above read "pointer or allocatable" where appropriate.

这篇关于Fortran模块中类型之间的循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆