7

简而言之,为什么这不起作用:

generic
   Max : in Positive;
package Modular_Gen_Issue is
   procedure Foo;
private
   type Mod_Thing is mod Max; -- NOK
   type Int_Thing is new Integer range 0 .. Max; -- OK

end Modular_Gen_Issue;

通过编译:

$ gnatmake modular_gen_issue.ads
gcc-4.4 -c modular_gen_issue.ads
modular_gen_issue.ads:6:26: non-static expression used for modular type bound
modular_gen_issue.ads:6:26: "Max" is not static constant or named number (RM 4.9(5))
gnatmake: "modular_gen_issue.ads" compilation error
$

如何传入单个数字并使用它来定义模块化类型?

是的,它必须是模块化类型!

4

2 回答 2

10

对不起,你不能。每当您声明模块化类型时,模数必须是静态值,即编译器可以立即计算出的值。这是行不通的。这适用于类型声明的许多部分,尤其是编译器需要的部分,以便确定对象需要多少位,或有关对象表示的其他特征。另一方面,在 Int_Thing 中,范围的上限不需要是静态的(编译器已经知道 Int_Thing 将表示为与 Integer 相同,并且范围用于边界检查但不使用来确定 Int_Thing 有多大)。

如果这是现实生活中的情况,并且您需要一个可以处理不同模块化类型的泛型,您可以将模块化类型本身设为泛型参数:

generic
    type Mod_Thing is mod <>;
package Modular_Gen_Issue is ...

(PS 在您的示例中,Mod_Thing 的范围是 0..Max-1,而不是 0..Max。)

于 2013-06-12T14:51:09.097 回答
3

除了 ajb 写的内容之外,请考虑通用包的以下用法:

procedure Foo (Bar : in Positive) is
   package Instance is new Modular_Gen_Issue (Max => Bar);
begin
   null;
end Foo;

在这里,包Instance是用一个非静态值创建的,每次调用Foo. 因为 Ada 允许这样做,所以编译器必须期望通用单元的任何参数都是非静态的。这就是为什么你不能在那里声明你的模块化类型,即使你可以用一个静态值来实例化你的包。

扩展 ajb 的建议,您可以执行以下操作:

generic
   type Mod_Thing_Base is mod <>;
package Modular_Gen_Issue is
   type Mod_Thing is new Mod_Thing_Base;
end Modular_Gen_Issue;

这样,您可以定义 Mod_Thing 的原始操作(直接将其作为参数是无法做到的)。

于 2013-06-13T06:28:55.380 回答