在通用包中定义模块类型

时间:2013-06-12 11:36:37

标签: ada

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

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
$

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

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

2 个答案:

答案 0 :(得分:10)

对不起,你不能。每当你声明一个模块类型时,模数必须是一个静态值,即编译器可以在那里找到的值。这不起作用。对于类型声明的许多部分都是如此,尤其是编译器需要的部分,以便计算对象需要的位数,或者有关对象表示的其他特征。另一方面,在Int_Thing中,范围的上限不需要是静态的(编译器已经知道Int_Thing将表示为与Integer相同,并且该范围用于边界检查但不使用确定Int_Thing的大小。

如果这是一个真实的情况,并且您需要一个可以处理不同模块类型的通用,那么您可以将模块类型本身作为通用参数:

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

(P.S。示例中的Mod_Thing范围为0..Max-1,而不是0..Max。)

答案 1 :(得分: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的基本操作(你不能直接将它作为参数)。