此问题基于对this question的回复(现已删除)。它更多地是关于术语而不是实际的编程语义。
究竟什么是通用的“实例化”?它是在编译时还是在运行时发生的?
我将参考Ada 2012标准的latest draft。
术语 generic_instantiation 的含义是明确的;它是一个句法结构,类似于
package Inst is new Generic_Package(This => That);
我的问题是关于动词“实例化”。
我一直认为“实例化”是在编译时发生的事情。它是通用模板的扩展,当编译器在编译单元中遇到 generic_instantiation 时就会发生。
但是其他来源提到“实例化”,至少可选地,在运行时发生。
要实例化通用单元,程序员传递实际 每个正式的参数。然后通用实例表现得很好 像任何其他单位一样。可以在以下实例化通用单元 运行时,例如在循环内。
这似乎意味着实例化可以在编译时或运行时发生。我认为这是指 generic_instantiation 的阐述,它确实在运行时发生 - 但是,所有的详细说明都是在运行时发生的,是吗?
我发现从Ada RM那里得到明确的答案是非常困难的。 “实例化”或“实例化”没有词汇表条目(附件N)。
我能找到的最接近的是12.2(通用机构)第2段中“动态语义学”下的声明:
通用机构的详细说明没有其他效果 确定通用单元可以从那时开始实例化 没有失败的Elaboration_Check。
间接意味着实例化是一个运行时事件。
动词“实例化”是否正确引用了编译时事件(扩展通用模板)?到运行时事件(详细说明 generic_instantiation )?如果是后者,我们称之为前者? Ada RM是否在这一点上是清晰的?
答案 0 :(得分:1)
根据规则12,13和14中 Static Semantics 部分中的the generic instantiation,它似乎是在编译时完成的。
但是the Gnat documentation在其精化顺序控制部分中,描述了在某些情况下会引发程序错误。只有在运行程序时才会抛出此类异常。
因此,据我所知,在编译时,编译器会检查参数是否支持您的泛型推送的操作和范围,但实际代码是在运行时完成的。
答案 1 :(得分:0)
“Instantiation”是创建类型实例(对象或派生类型)的行为。在谈到泛型时,它还可以指代创建包或子程序的实例。类型的实例是该类型的对象:
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
“精化”是准备诸如包或任务之类的构造以进行加载和执行的过程。但是,最近没有研究过这个。