Generics 泛型实例化何时发生(即,该词的含义是什么)?

Generics 泛型实例化何时发生(即,该词的含义是什么)?,generics,ada,Generics,Ada,这个问题是基于一个讨论(现已删除)的回应。它更多的是术语,而不是实际的编程语义 什么是泛型“实例化”?它是在编译时发生还是在运行时发生 我将参考ADA2012标准的最新版本 术语泛型实例化的含义是明确的;这是一个句法结构,类似于 package Inst is new Generic_Package(This => That); 我的问题是关于动词“实例化”的 我一直认为“实例化”是在编译时发生的。它是泛型模板的扩展,当编译器在编译单元中遇到泛型_实例化时就会发生 但其他来源提到在运行时

这个问题是基于一个讨论(现已删除)的回应。它更多的是术语,而不是实际的编程语义

什么是泛型“实例化”?它是在编译时发生还是在运行时发生

我将参考ADA2012标准的最新版本

术语泛型实例化的含义是明确的;这是一个句法结构,类似于

package Inst is new Generic_Package(This => That);
我的问题是关于动词“实例化”的

我一直认为“实例化”是在编译时发生的。它是泛型模板的扩展,当编译器在编译单元中遇到泛型_实例化时就会发生

但其他来源提到在运行时发生的“实例化”,至少是可选的

说:

要实例化一个通用单元,程序员需要传递实际的 每种形式的参数。然后,泛型实例的行为只是 和其他单位一样。可以在以下位置实例化通用单元: 运行时,例如在循环中

这似乎意味着实例化可以发生在编译时或运行时。我认为这是指泛型_实例化的精化,它确实发生在运行时——但是,所有精化都发生在运行时,是吗

我发现很难从Ada RM那里得到一个明确的答案。“实例化”或“实例化”没有术语表条目(附录N)

我能找到的最接近的是12.2(泛型主体)第2段“动态语义”下的这句话:

泛型主体的细化除了 确定从那时起可以实例化通用单元 在没有未通过检查的情况下

这间接意味着实例化是一个运行时事件

动词“实例化”是否正确地引用编译时事件(扩展通用模板)?到运行时事件(详细说明泛型_实例化)?如果是后者,我们怎么称呼前者?Ada RM在这一点上是否像需要的那样清晰?

“实例化”是创建类型实例(对象或派生类型)的行为。在谈到泛型时,它还可以指创建包或子程序的实例。类型的实例是该类型的对象:

type My_Type is
   record
      Range_Begin : Natural := 1;
      Range_End   : Natural := 15_000_000;
   end record;

type My_Type_Access is access all My_Type;

My_Object1 : My_Type_Access := new My_Type;  -- instantiation of My_Type 
                                             -- to create My_Object1

My_Array_Objects : array (Positive range 1 .. 250_000) of My_Type_Access :=
   (others => new My_Type);  -- creates an array of objects of My_Type

“精化”是为加载和执行而准备构造(如包或任务)的过程。但是,最近没有研究过这个问题。

根据规则12、13和14中的静态语义部分,它似乎是在编译时完成的

但是,在精化顺序控制部分,描述了在某些情况下会出现程序错误。只有在运行程序时才会引发此类异常


所以,据我所知,关键是,在编译时,编译器会检查参数是否支持泛型推送的操作和范围,但真正的代码是在运行时完成的。

在我看来,仅根据英语,实例化意味着创建一个实例,这听起来肯定像是运行时。@DonRoby:啊,但什么是实例“例如"? 如果一个实例是扩展模板后产生的代码,那么它就是编译时。@DonRoby:一个松散的类比:C宏扩展肯定发生在编译时,而不是运行时。Ada泛型显然不是一回事,但有一些相同的原则适用。对我来说,实例化和精化之间的区别在于“普通”单元只有一个可能的精化,但是泛型单元可以有多个实例化,从而导致多个精化。因此,我假设它可以发生在编译时或运行时。(因此存在歧义,并且需要回答这个问题)我建议我们等待其他Ada人员的启发,因为我怀疑我们正在进入一个我们已经讨论过的讨论……我看到“实例化”一词用来指创建一个类型的实例(对象),但这不是我所说的;在Ada中,这个术语几乎总是指泛型实例化。说它“在谈到泛型时可以引用包或子程序实例的创建”并不能真正回答这个问题;它没有说明创建是在编译时还是在运行时进行。是的。你说得很对。通用实例化可以发生在任何规范中——包、子程序或任务的声明性部分。一个泛型可以在另一个泛型的规范中实例化,在这种情况下,它在其父级实例化时生效。对于任何构造,在运行时细化规范都可能导致实例化——就像细化过程中创建常量或初始化变量一样。是的,这可能发生在一个循环中,如NWS所示。