Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ada 在泛型包中定义模块化类型_Ada - Fatal编程技术网

Ada 在泛型包中定义模块化类型

Ada 在泛型包中定义模块化类型,ada,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.

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

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
$
如何传入单个数字并使用它定义模块化类型


是的,它必须是模块式的

对不起,你不能。无论何时声明模块类型,模块都必须是一个静态值,即编译器可以立即计算出的值。这不管用。类型声明的许多部分都是如此,特别是编译器需要的部分,以确定对象需要多少位,或者对象表示的其他特性。另一方面,在Int_对象中,范围的上限不需要是静态的(编译器已经知道Int_对象将表示为相同的整数,范围用于边界检查,但不用于确定Int_对象的大小)

如果这是一种实际情况,并且您需要一个能够处理各种模块类型的泛型,那么您可以将模块类型本身作为泛型参数:

generic
    type Mod_Thing is mod <>;
package Modular_Gen_Issue is ...
通用
类型Mod_事物是Mod;
包模块化\u Gen\u问题是。。。

(P.S.在您的示例中,MyDyTo的范围将是0…Max,而不是0…Max.)

除了AJB所写的之外,请考虑以下通用包的用法:

procedure Foo (Bar : in Positive) is
   package Instance is new Modular_Gen_Issue (Max => Bar);
begin
   null;
end Foo;
这里,包
实例
是用一个非静态值创建的,该值可能会随着对
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_Base为Mod;
机组模块化\u Gen\u问题
类型Mod_Thing是新Mod_Thing_Base;
结束模块化问题;

通过这种方式,您可以定义Mod_Thing的基本操作(直接将其作为参数是无法做到的)。

经过一段时间的讨论后,是的,我也想知道如何操作!:-)如果这里没有乐趣,也许可以试试comp.lang.ada,至少可以从那里的一些语言律师那里得到一个理由。因为编译器知道一个正数有多少位,它的上限(max),并且知道一个模块类型的下限是0,我仍然不知道这与int_的例子有什么不同。编译器在看到类型声明时不知道上限(max),因为您还没有实例化泛型并给max一个值。是的,当它第一次处理泛型时,在你实例化它之前,它确实需要知道这一点。泛型与C宏不同,它只存储文本,在展开宏之前不会查看文本。泛型必须在实例化它们之前遵守规则。另一个注释:Int_Thing的最大区别在于Int_Thing是从现有类型(整数)派生的,编译器将使该类型的大小与其派生的类型相同<代码>0。。Max添加边界检查,但不更改大小。但是,当创建全新的非派生类型时,编译器确实需要影响静态大小的信息。如果你说的是
类型Int\u,那么范围是0。。Max
,这也是非法的。答案+注释解释了这里发生的事情。谢谢