在通用包中定义模块类型

NWS*_*NWS 7 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;
Run Code Online (Sandbox Code Playgroud)

编译:

$ 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
$
Run Code Online (Sandbox Code Playgroud)

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

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

ajb*_*ajb 10

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

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

generic
    type Mod_Thing is mod <>;
package Modular_Gen_Issue is ...
Run Code Online (Sandbox Code Playgroud)

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

  • 编译器在它看到类型声明时不知道上限(max),因为你没有实例化泛型和给定的max值.是的,在实例化它之前,它首先需要知道它在处理泛型时的情况.泛型不像C宏,它只存储文本,在扩展宏之前不会查看它.泛型必须在实例化之前遵守规则. (3认同)
  • 另一个评论:与Int_Thing的最大区别在于Int_Thing是从现有类型(整数)派生的,编译器将使类型的大小与它的派生大小相同.`0 .. Max`添加边界检查但不改变大小.但是在创建全新的非派生类型时,编译器确实需要影响大小的信息是静态的.如果你说`类型Int_Thing是范围0 ..最大`,那也是非法的. (2认同)