【发布时间】:2014-02-23 11:41:23
【问题描述】:
考虑下面的代码
module classes
Type AData
end Type
Type A
contains
procedure :: Work
end type
Type, extends(AData) :: BData
end Type
Type, extends(A) :: B
contains
procedure :: Work => Work2
end type
contains
subroutine Work(this, D)
class(A) :: this
class(*) :: D
end subroutine
subroutine Work2(this, D)
class(B) :: this
class(BData) :: D
end subroutine
end module classes
这有效吗?它被 ifort 接受并被 gfortran 拒绝(因为 Work2 的第二个参数中的类不相同)。
如果它无效,它在某些情况下显然很有用:对于更多不同类型的参数,后代过程必须有多个嵌套的“选择类型”语句才能将参数转换为预期的类型。如果在编译时就知道子类中参数的类型(以丢失一些编译时一致性检查为代价),这将非常冗长并且可能效率也较低。是否有编译器选项可以让 gfortran 接受这个结构,还是应该是 gcc 错误报告/功能请求?
--编辑--: 明确地说,Gfortran 4.9 主干给出 错误:覆盖过程“work”在 (1) 的参数不匹配:参数“d”中的类型不匹配 (CLASS(bdata)/CLASS(*))
ifort(但不是 gfortran)也允许诸如
之类的结构subroutine Work2(this, D)
class(B) :: this
class(*), target :: D
class(BData), pointer :: B
B=>D
end subroutine
因此似乎将类(星号)变量视为具有来自开发人员的“相信我,我知道它是什么类型”标签。对我来说,这似乎非常合理(如果谨慎使用),并且避免了选择类型操作的开销,有时还避免了冗长的多个嵌套选择类型语句。我知道进行盲类型转换的唯一其他有效方法是通过一个外部子例程推动事物,其中根本没有对参数进行类型检查(在 f90 中绕过传递任意类型参数的 horrible 方法)。
使用其他类型覆盖类(星型)过程的愿望也出现在基本上下文中,例如您想要传入函数和任意对象的最小化库。在这里,即使最小化器不知道,开发人员和特定函数实现也总是知道对象是什么类型,因此您不希望在使用 class(*) 参数的函数实现中执行“选择类型” .
【问题讨论】:
-
在您的代码上使用 gfortran 4.8.2 有人告诉我“错误:在 (1) 处覆盖过程 'work' 的参数不匹配:参数 'd' 中的类型/等级不匹配”这就是问题所在你是说?
-
编辑问题以添加更多信息
-
您关于允许的指针分配形式的附加信息与围绕过程特征匹配要求的原始问题并不真正相关。
-
class() 并不是你真正想要的“相信我”。 TS29113 是增强 C 互操作性的技术规范,增加了 TYPE() 和 DIMENSION(..) 以等效于 C 的 void *。虽然主要用于从 Fortran 调用到 C,但您可以使用这种方式声明带有参数的 Fortran 例程,但它通常需要 TRANSFER 才能将虚拟对象“强制转换”为已知类型。这是目前称为 Fortran 2015 的规范的一部分。
标签: fortran