0

当我们从具有传递过程指针的数据类型(类)创建多个实例时,是否在每个实例中复制实际过程(子例程/函数)?还是只是复制了指针?

例如,考虑以下可以正确编译和运行的代码。

模块 mod2
  隐式无

  私人的

  类型类类型
     整数 :: a, b, c
   包含
     过程 :: add => add_it
  结束类型 class_type

  公共 :: class_type

包含

  子程序 add_it(this)
    隐式无
    类(class_type),意图(inout)::这个

    这个%c = 这个%a + 这个%b

  结束子程序 add_it

端模块 mod2

程序测试员
  使用 mod2
  隐式无

  类型(class_type),维度(10)::objs

  objs(:) = class_type(1, 2, 0)

结束程序测试员

add_it从数据类型创建的 10 个对象中的每个对象中是否都有重复的子程序class_type?或者子程序的指令集是否add_it存储在某个地方以及指向它的指针,即"procedure :: add => add_it" 复制到每个对象中?

4

1 回答 1

2

通常两者都不是。请注意,这在很大程度上是特定于实现的——我在下面描述的是典型的,但不同的处理器可能会做不同的事情。

请注意,您的示例中没有过程指针。该类型class_type具有绑定。如果class_type有一个过程指针,事情就不同了。

绑定的典型实现是编译器创建一个机器级指针表,每个特定绑定都有一个条目,指针指向过程的代码。为程序中的每种类型创建一个表(有时称为“vtable”,来自用于 C++ 和类似语言中的虚拟成员函数的类似技术)。

对于多态对象(用 声明的东西CLASS),编译器然后创建一个描述符,该描述符具有一个机器级指针,指向对象的动态(运行时)类型的相关表。该指针有效地指示对象的动态类型,并可用于SELECT TYPE诸如SAME_TYPE_AS. 如果您有一个多态数组,编译器最初通常只会为整个数组创建一个描述符,因为数组中的各个元素都必须具有相同的动态类型。

当您在多态对象上调用绑定时,编译器会跟随指向 vtable 的指针,然后查找指向过程绑定的相关指针。

非多态对象(用 TYPE 声明的东西)不需要这样的描述符或指针取消引用,因为动态和声明的类型总是相同的,编译器知道声明的类型是什么,并且编译器在编译时知道哪个过程将叫做。

如果您有一个过程调用,其中非多态实际参数与多态虚拟参数相关联,那么编译器通常会创建必要的描述符作为进行过程调用的一部分。类似地,将多态数组元素传递给采用多态标量的过程。

您的代码的主程序不包含多态实体,并且您不调用任何过程,因此可能没有任何机器指针返回到 vtable。

每个对象的过程指针组件(PROCEDURE(xxx), POINTER :: yyy在类型声明的 CONTAINS 之前声明的组件)可能不同(包括数组中的每个元素都不同)。在这种情况下,典型的实现是存储指向相关过程代码的机器级指针(或者如果过程指针组件尚未关联,则为空指针)。

于 2014-02-16T00:23:30.473 回答