我不知道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相同。 由于两个模块中存在类似的循环依赖关系,为什么第一个编译但第二个不编译?
答案 0 :(得分:5)
工作代码和不工作代码之间的区别在于具有组件的pointer
属性的类型的位置。这个属性允许类型声明引用之前未定义的类型。
看看
type type2
type(type1) :: t1
integer :: x
end type type2
此处type1
类型的type2
组件不具有pointer
属性。这意味着必须先前已定义类型type1
。在你的第一个,工作,例子就是这样。在你的第二个,破碎的例子中,它不是。
看另一种类型
type type1
type(type2), pointer :: t2
end type type1
type2
组件具有指针属性。因此,在此引用之前不需要定义类型type2
。您可以在两个示例中看到这一点。
此要求在Fortran 2008标准中声明为
C440(R436)如果既未指定POINTER也未指定ALLOCATABLE属性,则component-def-stmt中的declaration-type-spec应指定内部类型或先前定义的派生类型。
我这里只关注pointer
属性。正如引用所暗示的那样,allocatable
属性也是如此。允许此后用allocatable
引用是Fortran 2008中的新增功能:在Fortran 2003中,需要pointer
属性。正如Vladimir F所评论的那样,所有编译器都没有实现这种新的自由(提供递归可分配组件)。在上文中,在适当的位置阅读“pointer
或allocatable
”。