Fortran模块中类型之间的循环依赖关系

我不知道Fortran模块中究竟是如何解析循环依赖关系的.以下模块使用ifort-2016和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

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

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的行为相同.
由于两个模块中存在类似的循环依赖性,为什么第一个编译但第二个不编译?

解决方法

工作代码和不工作代码之间的区别在于具有组件的指针属性的类型的位置.这个属性允许类型声明引用先前未定义的类型.

看着

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

这里type2类型的type1组件没有指针属性.这意味着类型type1必须先前已定义.在你的第一个,工作,例子就是这样.在你的第二个,破碎的例子中,它不是.

看着另一种类型

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

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

此要求在Fortran 2008标准中说明为

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.

我在这里把注意力限制在指针属性上.正如引用所暗示的那样,allocatable属性也是如此.允许以后使用allocatable引用是Fortran 2008中的新增功能:在Fortran 2003中,指针属性是必需的.正如Vladimir F所评论的那样,所有编译器都没有实现这种新的自由(提供递归可分配组件).在上面适当的读“指针或可分配”.

相关文章

什么是设计模式一套被反复使用、多数人知晓的、经过分类编目...
单一职责原则定义(Single Responsibility Principle,SRP)...
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强...
适配器模式将一个类的接口转换成客户期望的另一个接口,使得...
策略模式定义了一系列算法族,并封装在类中,它们之间可以互...
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,...